Search code examples
c#xmlxpathlinq-to-xmlxmldocument

C# can't query XML but can traverse the nodes?


Related to my other question.

I'm trying to read a node from an XML file that looks like this:

<?xml version="1.0" encoding="UTF-8" ?>
<AuthorIT>
    <Objects>
        <Media>don't care</Media>
        <Style>don't care</Style>
        <Book>don't care</Book>
        <Topic>don't care</Topic>
        <Topic>
            <Object>
                <Description>Performance Evidence</Description>
            </Object>
            <Text>This is what I want to select</Text>
        </Topic>
    </Objects>
</AuthorIT>

But I can't query it. I've tried XmlDocument, XPath, and Linq to XML.

I have verified on http://XPather.com that my XPath is correct.


            /* this doesn't work but the XPath has been verified */
            XPathNavigator nav;
            XPathDocument docNav;
            string xPath;

            docNav = new XPathDocument(localFile);
            nav = docNav.CreateNavigator();
            xPath = "//Topic[Object/Description = 'Performance Evidence']/Text";
            string value = nav.SelectSingleNode(xPath).Value;

I can traverse the XML nodes using XmlDocument, but I don't want a series of nested foreach loops in place of a single query.

 XmlDocument doc = new XmlDocument();
 doc.Load(localFile);
 XmlNodeList xmlNodes = doc.SelectNodes("/");

 /* direct query doesn't work, but traversing the nodes does? */
 foreach (XmlNode node in xmlNodes)
 {
     if (node.Name == "#document")
     {
         foreach (XmlNode subNode in node.ChildNodes)
         {
             if (subNode.Name == "AuthorIT")
             {
                 foreach (XmlNode subSubNode in subNode.ChildNodes)
                 {
                     if (subSubNode.Name == "Objects")
                     {
                         foreach (XmlNode subSubSubNode in subSubNode.ChildNodes)
                         {
                             if (subSubSubNode.Name == "Topic")
                             {
// I didn't finish writing this, because it's a ridiculous way to do it... but it works
                             }
                         }
                     }
                 }
             }
         }
     }
 }

Is there something I'm doing wrong?

Some property of the XML document that can cause this? (if so, how do I get around it?)


Solution

  • What I left out of the example XML was the key to the solution... Namespace!

    I found my answer on this other question: Using Xpath With Default Namespace in C#