tags:

views:

76

answers:

3

I'm wondering if there is a robust and graceful way using linq2xml to query an item deep within an xml hierarchy. For example:

<?xml version="1.0" encoding="utf-8" ?>
<data>
    <core id="01234">
        <field1>some data</field1>
        <field2>more data</field2>
        <metadata>
            <response>
              <status code="0">Success</status>
              <content>
                 <job>f1b5c3f8-e6b1-4ae4-905a-a7c5de3f13c6</job>
                 <id>id of the content</id>
              </content>
            </response>
        </metadata>
    </core>
</data>

With this xml how do I query the value of without using something like this:

var doc = XElement.Load("file.xml");
string id = (string)doc.Element("core")
    .Element("metadata")
    .Element("response")
    .Element("content")
    .Element("id");

I don't like the above approach because it is error prone (throws exception if any tag is missing in the hierarchy) and honestly ugly. Is there a more robust and graceful approach, perhaps using the sql-like syntax of linq?

A: 

I wouldn't use linq-to-xml, I would use XML and XPath. You could load the XML then use a XPath query to find the ID nodes. Like this:

System.Xml.XmlDocument xDoc = new System.Xml.XmlDocument;
xDoc.Load("file.xml");
Xml.XmlNodeList idList = xDoc.SelectNodes("//content/id");
tgolisch
Yes this is how I would have done it in the past, I'm trying to move away from XPath and into linq2xml for various reasons. Thanks nontheless.
BrettRobi
+1  A: 
        XDocument doc = XDocument.Load("file.xml");
        var xx = doc.Descendants("id").First().Value;
Wondering
Oh come on! I can't believe it is that simple. Now I feel stupid. Thanks Wondering ;-)
BrettRobi
+1  A: 

This will give you an IEnumerable with all the content/id elements. If you need one specific one, you will need to add the conditions

var ids = from content in doc.Descendants("content")
          select content.Element( "id" ).Value;
BioBuckyBall
Also a graceful answer. Thanks yetapb.
BrettRobi