views:

59

answers:

2

So i have an XML document that looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"&gt;
   <gesmes:subject>Reference rates</gesmes:subject>
   <gesmes:Sender>
       <gesmes:name>European Central Bank</gesmes:name>
   </gesmes:Sender>
   <Cube>
       <Cube time="2010-05-28">
           <Cube currency="USD" rate="1.2384"/>
           <Cube currency="JPY" rate="113.06"/>
       </Cube>
       <Cube time="2010-05-27">
           <Cube currency="USD" rate="1.2255"/>
           <Cube currency="JPY" rate="110.79"/>
       </Cube>
   </Cube>
</gesmes:Envelope>

Now suppose that I have an XmlNode timeNode that points to <Cube time="2010-05-28"> node and a document that points to the loaded XML document. Lets say I need to get the value of the rate attribute in the <Cube currency=USD" rate="1.2384"/> node by calling a SelectSingleNode(string xpath) method.

So far I was able to come up with this code:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable);
nsmgr.AddNamespace("ecb", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
nsmgr.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");


XmlNode currencyNode = timeNode.SelectSingleNode("descendant::ecb:Cube[@ecb:currency='USD']", nsmgr);

string rate = currencyNode.Attributes.GetNamedItem("rate").Value;

The problem here is that currencyNode is set to null here. I've checked the timeNode and it points to the correct node, so I guess the problem is with the path in the SelectSingleNode method, yet I fail to see where the problem is. I've checked other posts with similar problem but couldn't find anything that would solve mines. Any pointers will be appreciated.

+1  A: 

XML attributes don't have the a namespace by default, so you don't need to use the namespace prefix on them. Try just:

XmlNode currencyNode = timeNode.SelectSingleNode("descendant::ecb:Cube[@currency='USD']", nsmgr);

You also don't need to explicitly specify the descendant axis here since it will look at children by default, so you could also shorten it to:

XmlNode currencyNode = timeNode.SelectSingleNode("ecb:Cube[@currency='USD']", nsmgr);
Quartermeister
Thanks. Worked perfectly. Great pointer on attribute namespace, I didn't know that.
L.E.O
+2  A: 

Change your xpath to

descendant::ecb:Cube[@currency="USD"]
YoK
hmmm by the time I added my answer similar answer was posted :(.
YoK