SelectNodes和GetElementsByTagName之间的主要区别是什么。
答案 0 :(得分:9)
SelectNodes是一种特定于.NET / MSXML的方法,它获取XPath表达式的匹配节点列表。 XPath可以按标签名称选择元素,但也可以执行许多其他更复杂的选择规则。
getElementByTagName是一种DOM Level 1 Core标准方法,可用于多种语言(但在.NET中拼写为大写G
)。它只按标签名称选择元素;你不能要求它选择具有特定属性的元素,或者在标记名为a
的其他元素中使用标记名为b
的元素,或者像这样的任何聪明的东西。它更老,更简单,并且在某些环境中更快。
答案 1 :(得分:3)
SelectNodes
将XPath表达式作为参数,并返回与该表达式匹配的所有节点。
GetElementsByTagName
将标记名称作为参数,并返回具有该名称的所有标记。
SelectNodes
更具表现力,因为您可以将GetElementsByTagName
来电作为SelectNodes
来电,但不是相反。 XPath是表达XML节点集的一种非常强大的方式,提供了比名称更多的过滤方式。例如,XPath可以根据标记子项上的标记名称,属性名称,内部内容和各种聚合函数进行过滤。
答案 2 :(得分:0)
SelectNodes()是文档对象模型(DOM)(msdn)的Microsoft扩展。 Welbog和其他人提到的SelectNodes采用XPath表达式。我想在需要删除xml节点时提及与GetElementsByTagName()的区别。
提供的用户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变量中释放/删除引用。