SelectNodes и GetElementsByTagName - PullRequest
       48

SelectNodes и GetElementsByTagName

4 голосов
/ 25 марта 2010

Каковы основные различия между SelectNodes и GetElementsByTagName.

Ответы [ 3 ]

9 голосов
/ 25 марта 2010

SelectNodes - это метод, специфичный для .NET / MSXML, который получает список подходящих узлов для выражения XPath . XPaths может выбирать элементы по имени тега, но также может выполнять множество других, более сложных правил выбора.

getElementByTagName - это стандартный метод DOM Level 1 Core, доступный на многих языках (но пишется с большой буквы G в .NET). Он выбирает элементы только по имени тега; Вы не можете попросить его выбрать элементы с определенным атрибутом или элементы с именем тега a внутри других элементов с именем тега b или что-нибудь умное в этом роде. Он старше, проще, а в некоторых средах быстрее.

3 голосов
/ 25 марта 2010

SelectNodes принимает выражение XPath в качестве параметра и возвращает все узлы, которые соответствуют этому выражению.

GetElementsByTagName принимает имя тега в качестве параметра и возвращает все теги с таким именем.

SelectNodes, следовательно, более выразителен, поскольку вы можете написать любой вызов GetElementsByTagName как вызов SelectNodes, но не наоборот. XPath - это очень надежный способ выражения наборов узлов XML, предлагающий больше способов фильтрации, чем просто имя. XPath, например, может фильтровать по имени тега, именам атрибутов, внутреннему содержимому и различным агрегатным функциям также и для дочерних тегов.

0 голосов
/ 09 октября 2013

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.

...