【问题标题】:Using XPath to parse an XML document使用 XPath 解析 XML 文档
【发布时间】:2012-01-08 02:27:40
【问题描述】:

假设我有以下 xml(一个简单的例子)

<rows>
   <row>
      <name>one</name>
   </row>
   <row>
      <name>two</name>
   </row>
</rows>

我正在尝试使用 XmlDocument 和 XPath 来解析它(最终我可以制作一个行列表)。

例如...

XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

foreach(XmlNode row in doc.SelectNodes("//row"))
{
   string rowName = row.SelectSingleNode("//name").InnerText;
}

为什么在我的 foreach 循环中,rowName 总是“一”?我希望它在第一次迭代中是“一个”,在第二次迭代中是“两个”。

似乎 //name 获得了文档中的第一个实例,而不是我所期望的行中的第一个实例。毕竟,我是在“行”节点上调用该方法。如果这是“它是如何工作的”,那么任何人都可以解释我如何改变它来满足我的需要吗?

谢谢

【问题讨论】:

  • 按//row/name 选择它怎么样?这行得通吗?

标签: c# xpath xmldocument


【解决方案1】:

使用下面的

        doc.LoadXml(xml);

            foreach(XmlNode row in doc.SelectNodes("/rows/row"))
            {
                string rowName = row.SelectSingleNode("//name").InnerText.ToString();
            }

【讨论】:

  • 这将导致与我开始时相同的问题,对不起
  • 让我改写一下,大声笑,我摆脱了/rows,只是将其作为//row,它对我有用。
【解决方案2】:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);

foreach(XmlNode row in doc.SelectNodes("//row"))
{
   var rowName = row.SelectSingleNode("name");
}

您发布的代码实际上是否正确?我在 row.SelectNode() 上收到编译错误,因为它不是 XmlNode 的成员。

无论如何,我上面的示例有效,但假设&lt;row&gt; 节点中只有一个&lt;name&gt; 节点,因此如果不是这种情况,您可能需要使用SelectNodes() 而不是SelectSingleNode()

正如其他人所展示的,使用.InnerText 来获取值。

【讨论】:

    【解决方案3】:

    您的第二个 xpath 以 // 开头。这是/descendant-or-self::node() 的缩写,您可以看到它以/ 开头,这意味着它从文档的根目录 搜索,无论您在什么上下文中使用它。

    您可能想要以下之一:

    var rowName = row.SelectSingleNode("name");
    

    查找name 节点是row直接子节点,或者

    var rowName = row.SelectSingleNode(".//name");
    

    在导致 xpath 从上下文节点开始的第二个 xpath 中找到 name 节点 *anywhere undertherow. Note the.`。

    【讨论】:

      【解决方案4】:

      使用 LINQ to XML。在您的代码文件中包含using System.Xml.Linq;,然后执行以下代码以获取您的列表

      XDocument xDoc = XDocument.Load(filepath);
      IEnumerable<XElement> xNames;
      
      xNames = xDoc.Descendants("name");
      

      这将为您提供名称元素的列表。然后,如果你想把它变成List&lt;string&gt;,只需这样做:

      List<string> list = new List<string>();
      foreach (XElement element in xNames)
      {
          list.Add(element.value);
      }
      

      【讨论】:

        【解决方案5】:

        我会使用 SelectSingleNode,然后是 InnerText 属性。

        var rowName = row.SelectSingleNode("name").InnerText;
        

        【讨论】:

          【解决方案6】:

          问题出在您的第二个 XPath 查询中:

          //row
          

          这有一个全局范围,所以无论你从哪里调用它,它都会选择 all row 元素。

          如果您将表达式替换为以下内容,它应该可以工作:

          .//row
          

          【讨论】:

            【解决方案7】:

            使用相对路径,例如string rowName = row.SelectSingleNode("name").InnerText;.

            【讨论】:

              猜你喜欢
              • 2018-03-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-12-10
              • 1970-01-01
              • 2013-03-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多