Vincenzo Lo Palo
Vincenzo Lo Palo

Reputation: 1381

Parsing XML using LINQ in c#

In this xml file (http://www.studiovincent.net/list.xml):

<list version="1.0">
  <meta>
    <type>resource-list</type>
  </meta>
  <resources start="0" count="4">
    <resource classname="Quote">
      <field name="name">Vincent</field>
      <field name="username">Hill</field>
      <field name="age">31</field>
      <field name="hair">black</field>
    </resource>
    <resource classname="Quote">
      <field name="name">John</field>
      <field name="username">Tedelon</field>
      <field name="age">27</field>
      <field name="hair">brown</field>
    </resource>
    <resource classname="Quote">
      <field name="name">Michael</field>
      <field name="username">Lopez</field>
      <field name="age">20</field>
      <field name="hair">red</field>
    </resource>
    <resource classname="Quote">
      <field name="name">Frank</field>
      <field name="username">Lopez</field>
      <field name="age">25</field>
      <field name="hair">black</field>
    </resource>
  </resources>
</list>

using this code:

using System.Xml;
using.System.Xml.Linq;

XmlReader reader = XmlReader.Create("http://www.studiovincent.net/list.xml");
XElement el = XElement.Load(reader);
reader.Close();

var items = el.Elements("resources").Elements("resource").Descendants().DescendantNodes();

var items = from item in el.Elements("resources").Elements("resource").Descendants() 
            where item.Attribute("name").Value == "name" select item.FirstNode;

foreach (XNode node in items)
{
    Console.WriteLine(node.ToString());
}

I have this OUTPUT:

Vincent
John
Michael
Frank

Code working very good, but I need get value 31 which corresponds field name="age" where field name="name" is Vincent. How Can I get this result?

Upvotes: 4

Views: 19004

Answers (2)

Danish Arc Europe
Danish Arc Europe

Reputation: 1

Consider this below XML is there as one of the SQL table's column.

<Root>
  <Name>Dinesh</Name>
  <Id>2</Id>
</Root>

The objective of the query is to fetch the Name from the XML. In this example we will fetch the 'Dinesh' as the value.

var Query = (from t in dbContext.Employee.AsEnumerable()
where t.active == true 
select new Employee
{
    Id = t.AtpEventId,  
    Name = XDocument.Parse(t.Content).Descendants("Root").Descendants("Name").ToList().  
    Select(node => node.Value.ToString()).FirstOrDefault()  
});

Note the following:

  1. t.active == true is just an example to make some condition if needed.

  2. Please note, in the above LINQ query, always use the AsEnumerable, as I did in the first line.

  3. Descendants("Root").Descendants("Name") - here "Root" should be the element matching with the XML, and under Root we have Name element.

Upvotes: 0

C&#233;dric Bignon
C&#233;dric Bignon

Reputation: 13022

I recommend you do as you would when reading XML naturally.

In your code, try to find all the fields with the name attribute set to "name".

This process cannot be used to associate a name with an age. It is more natural to read the XML and check all resource elements. Then add to this element some information described in the field elements.

// Using LINQ to SQL
XDocument document = XDocument.Load("http://www.studiovincent.net/list.xml");  // Loads the XML document.
XElement resourcesElement = document.Root.Element("resources");  // Gets the "resources" element that is in the root "list" of the document.

XElement resourceElementVincent = (from resourceElement in resourcesElement.Elements("resource")// Gets all the "resource" elements in the "resources" element
                                    let fieldNameElement = resourceElement.Elements("field").Single(fieldElement => fieldElement.Attribute("name").Value == "name")  // Gets the field that contains the name (there one and only one "name" field in the "resource" element -> use of Single())
                                    where fieldNameElement.Value == "Vincent"  // To get only resources called "Vincent"
                                    select resourceElement).Single();  // We suppose there is one and only 1 resource called "Vincent" -> Use of Single()
XElement fieldAgeElement = resourceElementVincent.Elements("field").Single(fieldElement => fieldElement.Attribute("name").Value == "age");  // Gets the corresponding "age" field
int age = int.Parse(fieldAgeElement.Value, CultureInfo.InvariantCulture);  // Gets the age by Parse it as an integer
Console.WriteLine(age);

Does it do what you want?

Upvotes: 7

Related Questions