SelectNodes y GetElementsByTagName

¿Cuáles son las principales diferencias entre SelectNodes y GetElementsByTagName?

SelectNodes es un método específico de .NET / MSXML que obtiene una lista de nodos coincidentes para una expresión XPath . XPaths puede seleccionar elementos por nombre de etiqueta, pero también puede hacer muchas otras reglas de selección más complicadas.

getElementByTagName es un método estándar DOM Nivel 1 disponible en muchos idiomas (pero escrito con una G mayúscula en .NET). Selecciona elementos solo por nombre de etiqueta; no puede pedirle que seleccione elementos con un determinado atributo, o elementos con nombre de etiqueta a dentro de otros elementos con nombre de etiqueta b o cualquier cosa inteligente como esa. Es más antiguo, más simple y en algunos entornos más rápido.

SelectNodes toma una expresión XPath como parámetro y devuelve todos los nodos que coinciden con esa expresión.

GetElementsByTagName toma un nombre de etiqueta como parámetro y devuelve todas las tags que tienen ese nombre.

SelectNodes es, por lo tanto, más expresivo, ya que puede escribir cualquier llamada GetElementsByTagName como una llamada SelectNodes , pero no al revés. XPath es una forma muy robusta de express conjuntos de nodos XML, ofreciendo más formas de filtrado que solo el nombre. XPath, por ejemplo, puede filtrar por nombre de etiqueta, nombres de atributos, contenido interno y varias funciones agregadas en tags también.

SelectNodes () es una extensión de Microsoft para el modelo de objetos de documento (DOM) ( msdn ). Los SelectNodes mencionados por Welbog y otros toman la expresión XPath. Me gustaría mencionar la diferencia con GetElementsByTagName () cuando se necesita eliminar el nodo xml.

Respuesta y código proporcionado usuario chilberto en msdn foro

La siguiente prueba ilustra la diferencia al realizar la misma función (eliminar los nodos persona) pero utilizando el método GetElementByTagName () para seleccionar los nodos. Aunque se devuelve el mismo tipo de objeto, su construcción es diferente. SelectNodes () es una colección de referencias del documento xml. Eso significa que podemos eliminar del documento en un foreach sin afectar la lista de referencias. Esto se muestra por el recuento de la lista de nodos que no se ve afectada. GetElementByTagName () es una colección que refleja directamente los nodos en el documento. Eso significa que a medida que eliminamos los elementos en el padre, en realidad afecta la colección de nodos. Esta es la razón por la cual la lista de nodos no puede ser manipulada en un foreach pero tuvo que ser cambiada a un ciclo while.

.NET SelectNodes ()

  [TestMethod] public void TestSelectNodesBehavior() { XmlDocument doc = new XmlDocument(); doc.LoadXml(@"  1 j   2 j   1 j   3 j   "); 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(@"  1 j   2 j   1 j   3 j   ");; 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"); } 

Con SelectNodes () obtenemos colección / lista de referencias a nodos de documentos xml. Podemos manipular con esas referencias. Si eliminamos el nodo, el cambio será visible para el documento xml, pero la colección / lista de referencias es la misma (aunque el nodo que fue eliminado, sus puntos de referencia ahora son nulos -> System.NullReferenceException) Aunque realmente no sé cómo esto está implementado. Supongo que si usamos XmlNodeList nodeList = GetElementsByTagName () y eliminamos el nodo con nodeList [i] .ParentNode.RemoveChild (nodeList [i]) liberamos / eliminamos la referencia en la variable nodeList.