XPath last()无法正常工作

时间:2013-08-30 23:55:19

标签: c# xpath

我有以下xml

 <root>
    <data>
      <person>tewst</person>
      <data>
        <phone>djk</phone>
        <email>dsd</email>
      </data>
    </data>
  </root>

使用c#SelectSingleNode我试图进入第二个“数据”节点并在电子邮件标签后插入新元素调用“phone2”。 问题是我无法找到正确的“数据”节点。这是我用来实现的代码,它不起作用。任何帮助,将不胜感激。谢谢

XMLDocument doc = new XMLDocument("xml file here");
var node = doc.SelectSingleNode("//data[last()]");

XMLElement phone1 = doc.CreateElement("phone2");
phone1.InnerText = "12";
node.AppendChild(phone1);

问题是节点为空。

解决方案:

XMLDocument doc = new XMLDocument("xml file here");
var node = doc.SelectSingleNode("(//data)[last()]");

2 个答案:

答案 0 :(得分:4)

//data[last()]选择data个父节点作为其父节点的data个节点,因此它会在您的示例中选择2个节点:

1)data节点的最后root个孩子

<data>
    <person>tewst</person>
    <data>
        <phone>djk</phone>
        <email>dsd</email>
    </data>
</data>

2)和第一个data节点的最后一个data子节点

<data>
    <phone>djk</phone>
    <email>dsd</email>
</data>

要选择整个文档中的最后一个data,请使用:

(//data)[last()]
  • //data将为所有后代data元素生成节点集,嵌套与否,
  • [last()]将选择节点集的最后一个节点
  • 括号()位于//data周围,确保其被解释为//data然后[last()],而不是//然后data[last()]

答案 1 :(得分:1)

有几种不同的方法可以做到这一点。

(1)如果您知道XML的结构将始终如上所述 - “root”元素,恰好一个“数据”子元素,以及“数据”父元素下面的一个“数据”子元素,则可以使用XPath表达式直接访问第二个“data”元素:

XmlNode node = doc.SelectSingleNode("/root/data/data");

(2)如果“root”元素下面有多个“data”元素,那么您可以执行以下操作:

XmlNodeList nodeList = doc.SelectNodes("//data/data");

此XPath表达式将返回文档中每个顶级“data”元素下的第一个“data”元素。例如,如果您有这样的XML文档:

<root>
    <data>
      <person>tewst</person>
      <data>
        <phone>djk</phone>
        <email>dsd</email>
      </data>
    </data>
    <data>
      <person>two</person>
       <data>
        <phone>bbb</phone>
        <email>ddd</email>
       </data>
    </data>
</root>

...此代码的输出已剪切:

XmlNodeList nodeList = doc.SelectNodes("//data/data");

foreach (XmlNode parentData in nodeList)
    Console.WriteLine(parentData.InnerXml.ToString());

...将产生:

<phone>djk</phone><email>dsd</email>
<phone>bbb</phone><email>ddd</email>

希望这有帮助。