Search code examples
c#xmllinqtraversallinqpad

Getting nested XML attribute value using XmlDocument


Precursor

The bit you don't really need to know, but might help in solving the issue, is that I am writing a series of C# statements in LINQPad, that gets a collection of records from an ELMAH (error logging system) database, extracts the XML (AllXml) field from each record and loads each extract into an XmlDocument. Ok, that seems fairly easy, but now I need to traverse each document and get a particular value from it.

XML Structure Example

Note: I have removed any potentially confidential information here...

<error type="System.Exception" time="2013-06-11T17:27:28.0122874Z">
    <item name="PATH_INFO">
      <value string="/foo/bar/thisIsTheValueIWant.aspx" />
    </item>
    <item name="PATH_TRANSLATED">
      <value string="C:\site\foo\bar\thisIsPotentiallyAnotherValueIMightWant.aspx" />
    </item>
    <item name="QUERY_STRING">
      <value string="meh" />
    </item>
</error>

Consider that this XML exists as a string, I have loaded this like so:

XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlString);

Problem

It's not too difficult to get the value of a node, but in this instance, the value is stored as an attribute of a node, and I've no idea how to traverse that!

I basically need to get the value node nested in the item node with name, "PATH_INFO", and then get the value of the "string" attribute.

How can I achieve this?


Solution

  • [Once you have an XmlNode object, you can ask for its Attributes collection and get the one you want by name.

    An example:

    XmlDocument doc = new XmlDocument();
    doc.LoadXml(xmlString);
    XmlNode itemNode = doc.SelectSingleNode("/error/item[@name = 'PATH_INFO']");
    if (itemNode != null)
    {
        XmlNode value = itemNode.SelectSingleNode("value");
        String valueString = value.Attributes["string"].Value;
    }