SelectNodes和GetElementsByTagName

时间:2010-03-25 11:44:47

标签: html xml dom selectnodes getelementsbytagname

SelectNodes和GetElementsByTagName之间的主要区别是什么。

3 个答案:

答案 0 :(得分:9)

SelectNodes是一种特定于.NET / MSXML的方法,它获取XPath表达式的匹配节点列表。 XPath可以按标签名称选择元素,但也可以执行许多其他更复杂的选择规则。

getElementByTagName是一种DOM Level 1 Core标准方法,可用于多种语言(但在.NET中拼写为大写G)。它只按标签名称选择元素;你不能要求它选择具有特定属性的元素,或者在标记名为a的其他元素中使用标记名为b的元素,或者像这样的任何聪明的东西。它更老,更简单,并且在某些环境中更快。

答案 1 :(得分:3)

SelectNodesXPath表达式作为参数,并返回与该表达式匹配的所有节点。

GetElementsByTagName将标记名称作为参数,并返回具有该名称的所有标记。

因此,{p> SelectNodes更具表现力,因为您可以将GetElementsByTagName来电作为SelectNodes来电,但不是相反。 XPath是表达XML节点集的一种非常强大的方式,提供了比名称更多的过滤方式。例如,XPath可以根据标记子项上的标记名称,属性名称,内部内容和各种聚合函数进行过滤。

答案 2 :(得分:0)

SelectNodes()是文档对象模型(DOM)(msdn)的Microsoft扩展。 Welbog和其他人提到的SelectNodes采用XPath表达式。我想在需要删除xml节点时提及与GetElementsByTagName()的区别。

chilberto

提供的用户msdn forum的答案和代码

下一个测试通过执行相同的功能(删除人员节点)但通过使用GetElementByTagName()方法选择节点来说明差异。虽然返回了相同的对象类型,但它的结构却不同。 SelectNodes()是一个返回xml文档的引用的集合。这意味着我们可以在foreach中从文档中删除而不会影响引用列表。这通过不受影响的节点列表的计数来显示。 GetElementByTagName()是一个直接反映文档中节点的集合。这意味着当我们删除父项中的项时,实际上会影响节点的集合。这就是为什么nodelist不能在foreach中操作但必须更改为while循环的原因。

.NET SelectNodes()

    [TestMethod]
    public void TestSelectNodesBehavior()
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(@"<root>
                               <person>
                                 <id>1</id>
                                 <name>j</name>
                                </person>
                                <person>
                                  <id>2</id>
                                  <name>j</name>
                                </person>
                                <person>
                                  <id>1</id>
                                  <name>j</name>
                                 </person>
                                 <person>
                                   <id>3</id>
                                   <name>j</name>
                                  </person>
                                  <business></business>
                                </root>");

        XmlNodeList nodeList = doc.SelectNodes("/root/person");

        Assert.AreEqual(5, doc.FirstChild.ChildNodes.Count, "There should have been a total of 5 nodes: 4 person nodes and 1 business node");
        Assert.AreEqual(4, nodeList.Count, "There should have been a total of 4 nodes");

        foreach (XmlNode n in nodeList)
            n.ParentNode.RemoveChild(n);

        Assert.AreEqual(1, doc.FirstChild.ChildNodes.Count, "There should have been only 1 business node left in the document");
        Assert.AreEqual(4, nodeList.Count, "There should have been a total of 4 nodes");
    }

.NET GetElementsByTagName()

    [TestMethod]
    public void TestGetElementsByTagNameBehavior()
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(@"<root>
                               <person>
                                 <id>1</id>
                                 <name>j</name>
                                </person>
                                <person>
                                  <id>2</id>
                                  <name>j</name>
                                </person>
                                <person>
                                  <id>1</id>
                                  <name>j</name>
                                 </person>
                                 <person>
                                   <id>3</id>
                                   <name>j</name>
                                  </person>
                                  <business></business>
                                </root>");;

        XmlNodeList nodeList = doc.GetElementsByTagName("person");

        Assert.AreEqual(5, doc.FirstChild.ChildNodes.Count, "There should have been a total of 5 nodes: 4 person nodes and 1 business node");
        Assert.AreEqual(4, nodeList.Count, "There should have been a total of 4 nodes");

        while (nodeList.Count > 0)
            nodeList[0].ParentNode.RemoveChild(nodeList[0]);

        Assert.AreEqual(1, doc.FirstChild.ChildNodes.Count, "There should have been only 1 business node left in the document");
        Assert.AreEqual(0, nodeList.Count, "All the nodes have been removed");
    }

使用SelectNodes(),我们获得了对xml文档节点的引用的集合/列表。我们可以使用这些引用进行操作。如果我们删除节点,更改将对xml文档可见,但是引用的集合/列表是相同的(虽然已删除的节点,它的引用点现在为null - > System.NullReferenceException)虽然我真的不知道这是如何实现的。我想如果我们使用XmlNodeList nodeList = GetElementsByTagName()并使用nodeList [i]删除节点.ParentNode.RemoveChild(nodeList [i])是在nodeList变量中释放/删除引用。