0

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

两者的输出相同

本杰明富兰克林自传BenjaminFranklin8.99

我将有像 if(price > 10) 这样的条件然后获得标题。如何解决这个问题

4

2 回答 2

2

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

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

foreach (XPathNavigator titleNode in titleNodes)
{
    var title = titleNode.Value;
    Console.WriteLine(title);
}
于 2017-12-14T20:30:08.587 回答
2

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

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

返回一个,如文档XPathNodeIterator中所示,您需要通过旧的(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 MoveNext()

最初,枚举数位于集合中的第一个元素之前。在读取 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。它比旧的XmlDocumentAPI 简单得多。

于 2017-12-14T20:31:07.677 回答