SelectNodes () - это расширение Microsoft для объектной модели документа (DOM) ( msdn ).
SelectNodes, как упомянуто Welbog и другими, принимает выражение XPath. Я хотел бы упомянуть разницу с GetElementsByTagName (), когда необходимо удалить узел XML.
Ответ и код, предоставленный пользователем chilberto на форуме MSDN
Следующий тест иллюстрирует разницу, выполняя ту же функцию (удаляя узлы человека), но используя метод GetElementByTagName () для выбора узлов. Хотя возвращается один и тот же тип объекта, его конструкция отличается. SelectNodes () - это коллекция ссылок на документ xml. Это означает, что мы можем удалить из документа в foreach, не влияя на список ссылок. Это видно по количеству нодлиста, на которые это не влияет. GetElementByTagName () - это коллекция, которая напрямую отражает узлы в документе. Это означает, что, удаляя элементы в родительском элементе, мы фактически влияем на коллекцию узлов. Вот почему список узлов нельзя манипулировать в 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.