【问题标题】:XpathNavigator couldn't get the inner text of xmlXpathNavigator 无法获取 xml 的内部文本
【发布时间】:2018-05-28 23:46:27
【问题描述】:

这是我的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) 的条件,然后获得标题。如何解决这个问题

【问题讨论】:

    标签: c# xml xpathnavigator xpathnodeiterator


    【解决方案1】:

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

    XPathNodeIterator titleNodes = nav.Select("/bookstore/book[price>10]/author/title");
    
    foreach (XPathNavigator titleNode in titleNodes)
    {
        var title = titleNode.Value;
        Console.WriteLine(title);
    }
    

    【讨论】:

      【解决方案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 是未定义的。

      您看到的奇怪行为是在未定义值时使用 Current 的结果。 (我有点期待在这种情况下会引发异常,但所有这些类都非常古老——我相信可以追溯到 c# 1.1——而且编码标准当时没有那么严格。)

      如果您确定只有一个 &lt;price&gt; 节点并且不想遍历多个返回的节点,您可以使用 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 简单得多。

      【讨论】:

      • 我要获取标题,价格>9。如何添加此条件
      • @GANI - stackoverflow 上问题的首选格式是one question per post。如果您想知道XPathNodeIterator.Current 为何返回垃圾结果,我的回答会告诉您这一点。但是,如果您希望 XPath 查询查找价格大于 9 的所有书名,请参阅 Alexander Petrov 的 answer(或提出其他问题)。
      猜你喜欢
      • 2016-12-05
      • 1970-01-01
      • 1970-01-01
      • 2022-07-29
      • 2013-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      相关资源
      最近更新 更多