17

I have a problem

My XML File is here:

<altinkaynak>

   <DOVIZ>
     <ADI>Tarih</ADI>
     <ALIS>24.07.2013 18:59:45</ALIS>
     <SATIS/>
   </DOVIZ>
   <DOVIZ>
      <ADI>USD</ADI>
      <ALIS>1.9120</ALIS>
      <SATIS>1.9220</SATIS>
   </DOVIZ>
   <DOVIZ>
      <ADI>EUR</ADI>
      <ALIS>2.5280</ALIS>
      <SATIS>2.5430</SATIS>
   </DOVIZ> 
</altinkaynak>

How am I parse this XML file

I coded that way but I got a parse error message;

if (tip == DövizKuruTipi2.Alış)
Line 44: return Decimal.Parse(doc.SelectNodes("//ALTINKAYNAK/DOVIZ/ADI=" + dovizKuru2 + "/ALIS")[0].InnerText.Replace('.', ','));

Expression must evaluate to a node-set

RBT
  • 24,161
  • 21
  • 159
  • 240
ofince
  • 173
  • 1
  • 1
  • 7

4 Answers4

29

Reason for the Error

As per the error message, .SelectNodes() requires that the xpath string parameter evaluates to a node set, e.g. this xpath will return an XmlNodeList containing 3 nodes:

var nodeSet = document.SelectNodes("/altinkaynak/DOVIZ");

Supplying an xpath which returns a single node is also acceptable - the returned XmlNodeList will just have a single node:

var nodeSet = document.SelectNodes("(/altinkaynak/DOVIZ)[1]");

However, it is not possible to return non-node values, such as scalar expressions:

var nodeSet = document.SelectNodes("count(/altinkaynak/DOVIZ)");

Error: Expression must evaluate to a node-set.

Instead for XmlDocument, you would need to create a navigator, compile an expression, and evaluate it:

 var navigator = document.CreateNavigator();
 var expr = navigator.Compile("count(/altinkaynak/DOVIZ)");
 var count = navigator.Evaluate(expr); // 3 (nodes)

If you switch your Xml parsing stack from using XmlDocument to a Linq to Xml XDocument there is a much more concise way to evaluate scalar expressions:

var count = xele.XPathEvaluate("count(/altinkaynak/DOVIZ)");

Badly formed Xpath

This same error (Expression must evaluate to a node-set) is also frequently returned for xpaths which are invalid altogether

 var nodeSet = document.SelectNodes("{Insert some really badly formed xpath here!}");

Error: Expression must evaluate to a node-set.

OP's Question

You have an error in your Xpath. What you probably want is this:

doc.SelectNodes("//ALTINKAYNAK/DOVIZ[ADI='" + dovizKuru2 + "']/ALIS") // ...

which will return the ALIS child of the DOVIZ element which has an ADI child with a value of dovizKuru2 (which is presumably a variable for currency such as USD)

Community
  • 1
  • 1
StuartLC
  • 104,537
  • 17
  • 209
  • 285
  • 3
    Actually `Some/Really=badly[@formed='xpath']` is syntactically valid and returns a boolean. If you replace it by `A/B = C[@X=3]` you can see that it makes perfect sense. – Michael Kay Oct 07 '16 at 18:48
1

I was getting this error because my Xpath expression was invalid. I was using == for equality instead of a single =. My expression was [SomeNode == 'SomeValue'] but should have been [SomeNode = 'SomeValue'].

Aaron Jensen
  • 25,861
  • 15
  • 82
  • 91
0

I was getting this because I had // at the end of my Xpath by accident.

Incorrect

table.SelectNodes(".//tr[1]//td[1]//");

Correct

table.SelectNodes(".//tr[1]//td[1]");

metoyou
  • 639
  • 1
  • 7
  • 22
0

In my case I had commented a node1 tag in one of my config xml for debugging. So it was throwing this error.

I just removed the unwanted node tag. It worked.