XpathNavigator无法获取xml的内部文本

时间:2017-12-14 19:42:18

标签: c# xml xpathnavigator xpathnodeiterator

这是我的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>

这是我的代码

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;
}

两个

获得相同的输出
  

Benjamin FranklinBenjaminFranklin8.99的自传

我会有条件,如果(价格> 10)然后获得标题。如何解决这个问题

2 个答案:

答案 0 :(得分:2)

您可以直接在xpath表达式中使用condition。

XPathNodeIterator titleNodes = nav.Select("/bookstore/book[price>10]/author/title");

foreach (XPathNavigator titleNode in titleNodes)
{
    var title = titleNode.Value;
    Console.WriteLine(title);
}

答案 1 :(得分:2)

您在此处调用的方法XPathNavigator.Select()

var price = node.Select("price");

返回XPathNodeIterator,如docs所示,您需要通过旧的(c#1.0!)样式实际迭代它:

var price = node.Select("price");
while (price.MoveNext())
{
    string currentPriceValue = price.Current.Value;
    Console.WriteLine(currentPriceValue); // Prints 8.99
}

或更新的foreach样式,它做同样的事情:

var price = node.Select("price");
foreach (XPathNavigator currentPrice in price)
{
    string currentPriceValue = currentPrice.Value;
    Console.WriteLine(currentPriceValue); // 8.99
}

在上面的两个示例中,在第一次调用MoveNext()之后使用枚举器的当前值。在您的代码中,您在第一次调用MoveNext() 之前使用的是IEnumerator.Current 。正如docs

中所述
  

最初,枚举数位于集合中的第一个元素之前。在读取Current的值之前,必须调用MoveNext方法将枚举器前进到集合的第一个元素; 否则,电流未定义。

您看到的奇怪行为是在未定义值时使用Current的结果。 (我希望在这种情况下会抛出一个异常,但是所有这些类都非常陈旧 - 我相信c#1.1的时间 - 并且编码标准不那么严格了。)

如果您确定只有一个<price>节点并且不想迭代多个返回的节点,您可以使用LINQ语法来挑选该单个节点:

var currentPriceValue = node.Select("price").Cast<XPathNavigator>().Select(p => p.Value).SingleOrDefault();
Console.WriteLine(currentPriceValue); // 8.99

或切换到SelectSingleNode()

var currentPrice = node.SelectSingleNode("price");
var currentPriceValue = (currentPrice == null ? null : currentPrice.Value);
Console.WriteLine(currentPriceValue); // 8.99

最后,考虑切换到LINQ to XML以加载和查询任意XML。它比旧XmlDocument API简单得多。