BUG: Performance degradation when you call the GetElementsByTagName method multiple times (823928)



The information in this article applies to:

  • Microsoft Visual Studio .NET (2003), Professional Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2002), Professional Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2002), Enterprise Developer Edition

SYMPTOMS

When you call the GetElementsByTagName method multiple times, and you then add a node or delete a node from the XML document, the addition or the deletion of nodes is delayed.

CAUSE

This problem occurs because the GetElementsByTagName method returns an XmlNodeList collection that registers listeners on the NodeInserted and the NodeRemoved events. For example, when you call the GetElementsByTagName method ten times, the NodeInserted and the NodeRemoved events have ten listeners. Therefore, when you call the GetElementsByTagName method multiple times, the process of inserting and removing nodes is delayed.

WORKAROUND

To work around this problem, use the SelectNodes method instead of the GetElementsByTagName method. To do this, follow these steps:
  1. Replace the following statement in the Main procedure:
    nlist = Xmldoc.GetElementsByTagName("title")
    with the following statement:

    Microsoft Visual Basic .NET Code

     nlist = Xmldoc.SelectNodes("/book/title")

    Microsoft Visual C# .NET Code

    nlist = Xmldoc.SelectNodes("/book/title");
  2. On the Debug menu, click Start.
Note The following are the key differences between the GetElementsByTagName method and the SelectNodes method:
  • The GetElementsByTagName method takes an element name as a parameter, and the SelectNodes method takes an XPath expression as a parameter.
  • You can implement the GetElementsByTagName method with the XmlDocument type or the XmlElement type, and you can call the method with the XmlDocument object or the XmlElement object. The SelectNodes method is implemented by the XmlNode type. The XmlNode type is the base type for the XmlDocument type. The XmlDocument type can be called by a type that derives from the XmlNode type directly or indirectly. For example, the XmlDocument type can be called by the XmlDocument, the XmlElement, the XmlAttribute, the XmlEntity, or the XmlNotation types.
  • The GetElementsByTagName method can only return an XmlNodeList collection that comprises descendant elements that are relative to the XmlDocument object or the XmlElement object. The SelectNodes method is more powerful because it uses XPath expressions. You can also use the SelectNodes method to access sibling elements of the context XmlNode object, ancestor elements of the context XmlNode object, and XML nodes that are located anywhere in the hierarchy that can be accessed by specifying a valid XPath expression. Additionally, the scope of the SelectNodes method is not restricted to returning elements.

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.

MORE INFORMATION

Steps to Reproduce the Behavior

  1. Start Microsoft Visual Studio .NET
  2. On the File menu, point to New, and then click Project.
  3. Click Visual Basic Project or Visual C# Projects under Project Types, and then click Console Application under Templates.

    Note By default, Module1 is created in Visual Basic .NET and Class1 is created in Visual C# .NET.
  4. Add the following statement to the top of the code in the Module1.vb file.

    Visual Basic .NET Code

    Imports System.Xml

    Visual C# .NET Code

    using System.Xml;
  5. Add the following code to the Main procedure.

    Visual Basic .NET Code

    Dim Xmldoc As New XmlDocument()
    'load the Xml document from the specified string
    Xmldoc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'> <title>Pride And Prejudice</title> </book>")
    Dim i As Integer
    Dim nlist As XmlNodeList
    For i = 0 To 12000
          'get all book titles in the XML document using the GetElementsByTagName method
          nlist = Xmldoc.GetElementsByTagName("title")
    Next
    Console.WriteLine("Time before creating and appending the element: " + System.DateTime.Now.ToString())
    Dim node As XmlNode = Xmldoc.DocumentElement
    Dim elem As XmlElement
    'create an XML element
    elem = Xmldoc.CreateElement("Date")
    elem.InnerText = "Jan 20,2002"
    'add the node to the end of child nodes
    node.AppendChild(elem)
    Console.WriteLine("Time after creating and appending the element: " + System.DateTime.Now.ToString())
    Console.ReadLine()

    Visual C# .NET Code

    XmlDocument Xmldoc = new XmlDocument(); 
    //Load the Xml document from the specified string
    Xmldoc.LoadXml("<book genre='novel' ISBN='1-861001-57-5'><title>Pride And Prejudice</title></book>"); 
    int i; 
    XmlNodeList nlist;
    for(i=0;i<=12000;i++)
    {
       //Get all book titles in the XML document using the GetElementsByTagName method
       nlist = Xmldoc.GetElementsByTagName("title"); 
    }
    Console.WriteLine("Time before creating and appending the element: " + System.DateTime.Now.ToString());                  
    XmlNode node=Xmldoc.DocumentElement ;
    XmlElement elem;
    //Create an XML element
    elem = Xmldoc.CreateElement("Date");
    elem.InnerText = "Jan 20,2002";
    //Add the node to the end of child nodes
    node.AppendChild(elem);
    Console.WriteLine("Time after creating and appending the element: " + System.DateTime.Now.ToString());
    Console.ReadLine();
    
  6. On the Build menu, click Build Solution.
  7. On the Debug menu, click Start. Notice the output in the Console window. The addition of nodes is delayed for few seconds.

REFERENCES

For more information about the XmlDocument.GetElementsByTagName method, visit the following Microsoft Developer Network (MSDN) Web site:For more information about the XmlElement.GetElementsByTagName method, visit the following MSDN Web site:

Modification Type:MinorLast Reviewed:9/15/2005
Keywords:kbvs2002sp1sweep kbPerformance kbXML kbbug KB823928 kbAudDeveloper