amigo
amigo

Reputation: 155

C# - Parsing childnode attribute values from parent node only

Let's say we have the following XML file which look likes

<model uri="model1">
  <PriceData>
    <value price="24.28" date="2013-12-01"/>
    <value price="22.34" date="2013-12-02"/>
    <value price="24.12" date="2013-12-03"/>
 </PriceData>
</model>
<model uri="model2">
  <PriceData>
    <value price="24.28" date="2013-12-01"/>
    <value price="22.34" date="2013-12-02"/>
    <value price="24.12" date="2013-12-03"/>
 </PriceData>
</model>

and this can continue for many models and prices. I search a way to parse in different lists (or array) the price of each model without do it manually i.e. to preallocate lists etc. because the number of the model will not be the same all the time. So how can i make "buckets" of prices for different models? What i tried until now is

using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Collections.Generic;

namespace test
{
   class Program
   {
       static void Main(string[] args)
       {
          string file = @"C:\Users\user\Desktop\test.xml";
          XDocument doc = XDocument.Load(file);
          List<string> priceData = new List<string>();
          List<string> modelName = new List<string>();
          foreach (var imovel in doc.Root.Descendants("model"))
          {
             modelName.Add(imovel.Attribute("uri").Value);
          }
          int modelNum = modelName.Count();
          foreach (var item in doc.Descendants("value"))
          {
               var doubleAttr = item.Attribute("price");
               if (doubleAttr == null) continue;
               priceData.Add(item.Attribute("price").Value);
          }            
          //Console.WriteLine(modelName[0]);
          Console.ReadKey();
       }
   }
}

But in this case the second foreach loop takes the prices of all models in a list. I try to get some ideas...my cup of coffee is empty :-(

Upvotes: 0

Views: 895

Answers (2)

amigo
amigo

Reputation: 155

So i found a solution which gives me the result that i was looking for

  string file = @"C:\Users\user\Desktop\test.xml";
  string id = "model1"; /* here you can set a parse dialog*/  
  string ModelID = "//model[@uri='" + id + "']";
  List<string> priceData = new List<string>();
  XmlDocument xDoc = new XmlDocument();
  xDoc.Load(file);
  XmlNodeList PriceNodeList = xDoc.SelectNodes(ModelID + "/PriceData/value");

  //looping through the all the node details one by one          
   foreach (XmlNode x in PriceNodeList)
   {
   //for the current Node retrieving all the Attributes details            
   var price = x.Attributes["double"];
   if (price == null) continue;
   priceData.Add(price.Value);
   }

Upvotes: 0

Tony
Tony

Reputation: 7445

Try LINQ:

string file = @"C:\Users\user\Desktop\test.xml";
XDocument doc = XDocument.Load(file);

XDocument doc = XDocument.Parse(file);
var list = doc.Elements("model").Select(x => new {
    Uri = x.Attribute("uri").Value,
    Prices = x.Element("PriceData").Elements().Select(y => new {
        Price = y.Attribute("price"),
        Date = y.Attribute("date")
    }).ToList()
}).ToList();

Here is the fiddle: http://dotnetfiddle.net/QbtKgo

But actually this code may be different depeding on your xml schema, but it shows the approach.

Upvotes: 1

Related Questions