Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# XmlDocument SelectNodes

Tags:

c#

xml

xpath

I have an xml document with a root element, two child elements, 'diagnostic' and 'results'. The 'results' element then has an arbitrary number of elements with the name 'result'

When this is loaded into an XmlDocument it is easy to navigate the structure and see that this is exactly how things operate. I can write a recursive function that picks out all the "result" elements. The XmlDocument.SelectNodes("//results") finds a node no problem.

However, * XmlDocument.SelectNodes("//results/result") finds nothing.
* XmlDocument.SelectNodes("//result") finds nothing.

I've talked to a co-worker and he's had grief using Xpath in XmlDocument.SelectNodes. Anyone else run into this kind of problem? Any solutions?

XML FILE:

<?xml version="1.0" encoding="UTF-8"?>
<query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="10" yahoo:created="2009-08-07T10:19:59Z" yahoo:lang="en-US" yahoo:updated="2009-08-07T10:19:59Z" yahoo:uri="http://query.yahooapis.com/v1/yql?q=select+*+from+search.news+where+query%3D%22Tanzania%22">
    <diagnostics>
        <publiclyCallable>true</publiclyCallable>
        <url execution-time="47"><![CDATA[http://boss.yahooapis.com/ysearch/news/v1/Tanzania?format=xml&start=0&count=10]]></url>
        <user-time>49</user-time>
        <service-time>47</service-time>
        <build-version>2579</build-version>
    </diagnostics>
    <results>
        <result xmlns="http://www.inktomi.com/">
            <abstract>Kakungulu Cup winners SC Villa face Tanzania’s Simba SC this afternoon at the National stadium in Dar es salaam. “We had a very tiresome journey. The road was so bad and the road blocks were so many. However, we finally reached but the boys were so tired,” said Kato.</abstract>
            <clickurl>http://lrd.yahooapis.com/_ylc=X3oDMTQ4cXAxcnRoBF9TAzIwMjMxNTI3MDIEYXBwaWQDb0pfTWdwbklrWW5CMWhTZnFUZEd5TkouTXNxZlNMQmkEY2xpZW50A2Jvc3MEc2VydmljZQNCT1NTBHNsawN0aXRsZQRzcmNwdmlkA21VVGlta2dlQXUzeEYuM0xGQkQzR1pUU1FIS0dORXA4cUk4QUJJX1U-/SIG=12vhpskdd/**http%3A//www.monitor.co.ug/artman/publish/sports/SC_Villa_face_Simba_in_Tanzania_89289.shtml</clickurl>
            <date>2009/08/07</date>
            <language>english</language>
            <source>The Monitor</source>
            <sourceurl>http://www.monitor.co.ug/</sourceurl>
            <time>20:22:32</time>
            <title>SC Villa face Simba in Tanzania</title>
            <url>http://www.monitor.co.ug/artman/publish/sports/SC_Villa_face_Simba_in_Tanzania_89289.shtml</url>
        </result>

XPATH

doc.SelectNodes("//result") produces no hits.

like image 786
Daniel Avatar asked Aug 07 '09 23:08

Daniel


2 Answers

Rob and Marc's answers are probably going in the right direction - XmlDocument + namespaces + XPath can be a bit of a pain.

If you're able to use .NET 3.5, I suggest you use LINQ to XML instead. That would make it really easy:

XDocument doc = XDocument.Load("foo.xml");
XNamespace ns = "bar";
var results = doc.Descendants(ns + "result");

foreach (var result in results)
{
    ...
}

Basically LINQ to XML is a superior API in almost every way, in my experience :) (I believe there are some capabilities it's missing, but if you have access to .NET 3.5 it's definitely worth at least trying.)

like image 135
Jon Skeet Avatar answered Sep 28 '22 16:09

Jon Skeet


It sounds to me like namespaces are the issues; you generally need to enlist the help of an XmlNamespaceManager for this, and use an alias in your queries, i.e.

doc.SelectNodes("//x:results/x:result", nsmgr);

(where x is defined in nsmgr as an alias to the given namespace)

like image 28
Marc Gravell Avatar answered Sep 28 '22 17:09

Marc Gravell