SelectNodes 和 GetElementsByTagName 之间的主要区别是什么。
3 回答
SelectNodes是一种特定于 .NET/MSXML 的方法,用于获取XPath表达式的匹配节点列表。XPath 可以通过标签名称选择元素,但也可以执行许多其他更复杂的选择规则。
getElementByTagName是一种 DOM 1 级核心标准方法,可用于多种语言(但G
在 .NET 中拼写为大写)。它仅通过标签名称选择元素;您不能要求它选择具有特定属性的元素,或者在具有标签名称a
的其他元素中具有标签名称的元素b
或任何类似的聪明东西。它更旧、更简单,并且在某些环境中更快。
SelectNodes
将XPath表达式作为参数并返回与该表达式匹配的所有节点。
GetElementsByTagName
将标签名称作为参数并返回具有该名称的所有标签。
SelectNodes
因此更具表现力,因为您可以将任何GetElementsByTagName
调用编写为SelectNodes
调用,但反之则不行。XPath 是一种非常健壮的方式来表达 XML 节点集,它提供了比名称更多的过滤方式。例如,XPath 还可以按标签名称、属性名称、内部内容以及标签子项上的各种聚合函数进行过滤。
SelectNodes() 是 Microsoft 对文档对象模型 (DOM) ( msdn ) 的扩展。Welbog 和其他人提到的 SelectNodes 采用 XPath 表达式。当需要删除 xml 节点时,我想提一下与 GetElementsByTagName() 的区别。
下一个测试通过执行相同的功能(删除人员节点)但使用 GetElementByTagName() 方法来选择节点来说明差异。尽管返回了相同的对象类型,但它的构造是不同的。SelectNodes() 是对 xml 文档的引用集合。这意味着我们可以在 foreach 中从文档中删除,而不会影响参考列表。这通过不受影响的节点列表的计数来显示。GetElementByTagName() 是一个直接反映文档中节点的集合。这意味着当我们删除父项中的项目时,我们实际上会影响节点的集合。这就是为什么不能在 foreach 中操作节点列表而必须将其更改为 while 循环的原因。
.NET 选择节点()
[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 变量中的释放/删除引用。