BUG: XmlNamespaceManager Does Not Correctly Atomize Strings During Namespace Lookups (324996)



The information in this article applies to:

  • Microsoft .NET Framework 1.0
  • Microsoft .NET Framework 1.1
  • Microsoft .NET Framework Class Libraries 1.0
  • Microsoft .NET Framework Class Libraries 1.1

This article was previously published under Q324996

SYMPTOMS

The LookupNamespace and LookupPrefix methods of the XmlNamespaceManager class may return a null value even when a matching namespace definition has been added to the XmlNamespaceManager object. This problem is only noticed when you use the NameTable of an XmlDocument to construct the XmlNamespaceManager object instance.

CAUSE

XmlNamespaceManager does not correctly atomize strings while it executes namespace lookups when the NameTable of an XmlDocument is used to construct the XmlNamespaceManager object and a string value is used to directly specify the namespace prefix or URI to look up.

RESOLUTION

Use the Get method of the NameTable property of the XmlNamespaceManager object to supply the prefix and URI parameters when you execute the LookupNamespace and LookupPrefix methods. Alternatively, you can supply a new NameTable object instance when you construct the XmlNamespaceManager object.

STATUS

Microsoft has confirmed that this is a bug in the implementation of the XmlNamespaceManager class in the System.Xml Microsoft .NET Framework namespace.

MORE INFORMATION

Steps to Reproduce the Behavior

To re-create the described problem by using a Visual Basic .NET Console Application project, follow these steps:
  1. In Microsoft Visual Studio .NET, create a new Microsoft Visual Basic .NET Console Application project named XmlNsMgrRepro.
  2. Import the following namespace:
    Imports System.Xml
    					
  3. Use the following XML to create and add an XML file named Booksns.xml to the project:
    <?xml version='1.0'?>
    <!-- This file represents a fragment of a book store inventory database -->
    <bookstore xmlns="MyUrn:books" xmlns:auth="MyUrn:Authors">
      <book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <auth:author>
          <auth:first-name>Benjamin</auth:first-name>
          <auth:last-name>Franklin</auth:last-name>
        </auth:author>
        <price>8.99</price>
      </book>
      <book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <auth:author>
          <auth:first-name>Herman</auth:first-name>
          <auth:last-name>Melville</auth:last-name>
          <auth:degree from="Trenton U">B.A.</auth:degree>
        </auth:author>
        <price>11.99</price>
      </book>
      <book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <auth:author>
          <auth:first-name>William</auth:first-name>
          <auth:last-name>Plato</auth:last-name>
          <auth:degree from="Harvard">Ph.D.</auth:degree>
        </auth:author>
        <price>9.99</price>
      </book>
    </bookstore>
    					
  4. Paste the following code in the Sub Main() procedure:
    Dim doc As New XmlDocument()<BR/>
    Dim FilePath As String = CurDir() + "\.."
    doc.Load(FilePath + "\booksNS.xml")
    
    Dim AuthorNodes As XmlNodeList
    Dim AuthorNode As XmlNode
    
    Dim XmlNsMgr As New XmlNamespaceManager(doc.NameTable)
    
    'SUPPLYING A NEW NameTable OBJECT INSTANCE WILL ALSO FIX THE PROBLEM.
    'Dim XmlNsMgr As New XmlNamespaceManager(New NameTable())
    
    XmlNsMgr.AddNamespace("bk", "MyUrn:books")
    XmlNsMgr.AddNamespace("auth", "MyUrn:Authors")
    
    Console.WriteLine("Prefix for MyUrn:books : " & XmlNsMgr.LookupPrefix("MyUrn:books")) 'RETURNS NULL
    Console.WriteLine("Namespace URI for bk prefix : " & XmlNsMgr.LookupNamespace("bk")) 'RETURNS THE NAMESPACE URI
    
    Console.WriteLine("---------------")
    
    Console.WriteLine("Prefix for MyUrn:Authors : " & XmlNsMgr.LookupPrefix("MyUrn:Authors")) 'RETURNS NULL
    Console.WriteLine("Namespace URI for auth prefix : " & XmlNsMgr.LookupNamespace("auth")) 'RETURNS NULL
    
    'DOING THE FOLLOWING INSTEAD OF SUPPLYING A NEW NameTable OBJECT
    'WHEN CONSTRUCTING THE XmlNamespaceManager OBJECT WILL ALWAYS WORK AS EXPECTED.
    
    'Console.WriteLine("Prefix for MyUrn:books : " & XmlNsMgr.LookupPrefix(XmlNsMgr.NameTable.Get("MyUrn:books")))
    'Console.WriteLine("Namespace URI for bk prefix : " & XmlNsMgr.LookupNamespace(XmlNsMgr.NameTable.Get("bk")))
    
    'Console.WriteLine("---------------")
    
    'Console.WriteLine("Prefix for MyUrn:Authors : " & XmlNsMgr.LookupPrefix(XmlNsMgr.NameTable.Get("MyUrn:Authors")))
    'Console.WriteLine("Namespace URI for auth prefix : " & XmlNsMgr.LookupNamespace(XmlNsMgr.NameTable.Get("auth")))
    
    Dim response As String = Console.ReadLine
    					
  5. Review the code and read the inline comments. Notice that the active code uses string values to directly supply the namespace and prefix parameters when it executes the LookupPrefix and LookupNamespace methods of the XmlNamespaceManager object. Also notice that the NameTable of the XmlDocument in which the source XML is loaded is used to create an instance of the XmlNamespaceManager object.
  6. Save and build the project.
  7. Execute the project and view the output. Notice that the LookupPrefix method does not return the prefix names (it returns NULLs) for both of the specified namespace URIs (MyUrn:books and MyUrn:Authors). Also notice that the LookupNamespace method returns the namespace URI only for the first prefix definition that is added to the XmlNamespaceManager (the prefix bk). The namespace URI for the second prefix definition (the prefix auth) is not returned as expected.
  8. Press any key to close the console window and stop the project.
  9. Comment the currently active Console.WriteLine statements in the code and uncomment the Console.WriteLine statements that use the Get method of the NameTable object property of the XmlNamespaceManager object to supply the prefix and URI parameters when the LookupNamespace and LookupPrefix methods are executed.
  10. Save and rebuild the project.
  11. Execute the project and examine the output. This time, both the LookupNamespace and LookupPrefix method calls return the expected output. Press any key to close the console window and stop the project. Note from the comments in the code that another workaround is to supply a new NameTable object instance when the XmlNamespaceManager object is instantiated. When you do this, string values can be used directly to supply the namespace URI and prefix parameters while the LookupPrefix and LookupNamespace methods are executed.

Modification Type:MajorLast Reviewed:9/18/2003
Keywords:kbbug kbpending KB324996