This is my xml
<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<author>
<title>The Autobiography of Benjamin Franklin</title>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<author>
<title>The Confidence Man</title>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
</bookstore>
here is my code
XPathNavigator nav;
XPathNodeIterator nodesList = nav.Select("//bookstore//book");
foreach (XPathNavigator node in nodesList)
{
var price = node.Select("price");
string currentPrice = price.Current.Value;
var title = node.Select("author//title");
string text = title.Current.Value;
}
am getting the same output for both
The Autobiography of Benjamin FranklinBenjaminFranklin8.99
I will be having condition like if(price > 10) then get the title. how to fix this
The method XPathNavigator.Select()
that you are calling here:
var price = node.Select("price");
Returns an XPathNodeIterator
, so as shown in the docs you need to actually iterate through it, through either the old (c# 1.0!) style:
var price = node.Select("price");
while (price.MoveNext())
{
string currentPriceValue = price.Current.Value;
Console.WriteLine(currentPriceValue); // Prints 8.99
}
Or the newer foreach
style, which does the same thing:
var price = node.Select("price");
foreach (XPathNavigator currentPrice in price)
{
string currentPriceValue = currentPrice.Value;
Console.WriteLine(currentPriceValue); // 8.99
}
In both examples above, the enumerator's current value is used after the first call to MoveNext()
. In your code, you are using IEnumerator.Current
before the first call to MoveNext()
. And as explained in the docs:
Initially, the enumerator is positioned before the first element in the collection. You must call the MoveNext method to advance the enumerator to the first element of the collection before reading the value of Current; otherwise, Current is undefined.
The odd behavior you are seeing is as a result of using Current
when the value is undefined. (I would sort of expect an exception to be thrown in such a situation, but all these classes are very old -- dating from c# 1.1 I believe -- and coding standards were less stringent then.)
If you are sure there will be only one <price>
node and don't want to have to iterate through multiple returned nodes, you could use LINQ syntax to pick out that single node:
var currentPriceValue = node.Select("price").Cast<XPathNavigator>().Select(p => p.Value).SingleOrDefault();
Console.WriteLine(currentPriceValue); // 8.99
Or switch to SelectSingleNode()
:
var currentPrice = node.SelectSingleNode("price");
var currentPriceValue = (currentPrice == null ? null : currentPrice.Value);
Console.WriteLine(currentPriceValue); // 8.99
Finally, consider switching to LINQ to XML for loading and querying arbitrary XML. It's just much simpler than the old XmlDocument
API.