XpathNavigator 无法获取 xml 的内部文本

XpathNavigator couldn't get the inner text of xml

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

两个

得到相同的输出

The Autobiography of Benjamin FranklinBenjaminFranklin8.99

我将遇到类似 if(price > 10) 的条件,然后获得标题。如何解决这个问题

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

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

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

您在这里调用的方法XPathNavigator.Select()

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

Returns 一个 XPathNodeIterator, so as shown in the 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() 之后使用。在您的代码中,您使用的是 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.

您看到的奇怪行为是在未定义值时使用 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.

简单得多