tags:

views:

1795

answers:

3

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"&gt;
    <diagnostics>
        <publiclyCallable>true</publiclyCallable>
        <url execution-time="47"><![CDATA[http://boss.yahooapis.com/ysearch/news/v1/Tanzania?format=xml&amp;start=0&amp;count=10]]&gt;&lt;/url&gt;
        <user-time>49</user-time>
        <service-time>47</service-time>
        <build-version>2579</build-version>
    </diagnostics>
    <results>
        <result xmlns="http://www.inktomi.com/"&gt;
            <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&lt;/clickurl&gt;
            <date>2009/08/07</date>
            <language>english</language>
            <source>The Monitor</source>
            <sourceurl>http://www.monitor.co.ug/&lt;/sourceurl&gt;
            <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&lt;/url&gt;
        </result>

XPATH

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

+2  A: 

Have you got a sample of the xml concerned?

Is it possible that your "result" elements are actually in a different namespace to the "results" elements? Are there any qualifying prefixes on the elements?

Rob Levine
I added the xml, thanks for the response, it looks like you were right!
Daniel
+4  A: 

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)

Marc Gravell
Thanks Mark, that was exactly it.
Daniel
+3  A: 

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.)

Jon Skeet
Thanks Jon, I did switch to LINQ and it is much nicer! :)
Daniel