none
Why getElementsByTagName doesn't work if default namespace defined

    Question

  • MSDN says this function will omit namespaces when query:

    The getElementsByTagName method simulates the matching of the provided argument against the result of the tagName property of IXMLDOMElement When executed, it does not recognize or support namespaces.

    However, I find that it is not true in my code,

    =============================

    Dim xmlDoc As New MSXML2.DOMDocument40
    xmlDoc.async = False
    xmlDoc.load("Test.xsl") 
    
    Dim nodeList As MSXML2.IXMLDOMNodeList
    nodeList = xmlDoc.getElementsByTagName("*") 
    Dim length As Int32
    length = nodeList.length
    For index As Int32 = 0 To length - 1 
    Dim element As MSXML2.IXMLDOMElement
    element = nodeList.item(index) 
    Debug.Print(element.tagName) 
    Next
    
    Dim nodeListTitle As MSXML2.IXMLDOMNodeList
    nodeListTitle = xmlDoc.getElementsByTagName("TITLE") 
    length = nodeListTitle.length
    
    



    ==================
    The XSL file is, 

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/REC-html40" version="1.0">
    <xsl:template match="TaskReport">
    <head> <TITLE>Task Report</TITLE> </head> </xsl:template> </xsl:stylesheet>


    ======================
    The output is,

    xsl:stylesheet
    xsl:template
    head
    TITLE

    ***However, the query of "TITLE" doesn't work(length is 0). Any ideas are more than welcome!

     

    Monday, February 01, 2010 3:10 AM

Answers

  • Unfortunately SelectionLanguage in MSXML3 affects selectSingleNode and selectNodes but not getElementByTagName. You can neither specify the default namespace in getElementByTagName, nor omit default namespace in getElementByTagName as your TITLE element does have its namespace. Looks like XPath is the only way out, or push Microsoft to implement DOM level 2 with getElementsByTagNameNS support.
    • Marked as answer by RogerCui Wednesday, February 03, 2010 2:45 PM
    Monday, February 01, 2010 3:59 PM

All replies

  • As stated in the Remarks section of getElementsByTagName function:

    The getElementsByTagName method simulates the matching of the provided argument against the result of the tagName property of IXMLDOMElement. When executed, it does not recognize or support namespaces. Instead, you should use the selectNodes method, which is faster in some cases and can support more complex searches.

    I don't have VB installed, here is the sample vbscript code for your reference:

    Set xmlDoc = CreateObject("Msxml2.DOMDocument.4.0") 
    xmlDoc.async = False
    xmlDoc.load("Test.xsl") 
    
    Set nodeList = xmlDoc.getElementsByTagName("*") 
    length = nodeList.length
    For index = 0 To length - 1 
      Set element = nodeList.item(index) 
      Wscript.Echo element.tagName 
    Next
    
    xmldoc.setProperty "SelectionNamespaces", "xmlns:xsl='http://www.w3.org/TR/REC-html40'"
    Set head = xmlDoc.selectSingleNode("//xsl:TITLE")
    Wscript.Echo head.tagName
    Monday, February 01, 2010 8:34 AM
  • As stated in the Remarks section of getElementsByTagName function:

    The getElementsByTagName method simulates the matching of the provided argument against the result of the tagName property of IXMLDOMElement. When executed, it does not recognize or support namespaces. Instead, you should use the selectNodes method, which is faster in some cases and can support more complex searches.

    I don't have VB installed, here is the sample vbscript code for your reference:

    Set xmlDoc = CreateObject("Msxml2.DOMDocument.4.0") 
    
    xmlDoc.async = False
    
    xmlDoc.load("Test.xsl") 
    
    
    
    Set nodeList = xmlDoc.getElementsByTagName("*") 
    
    length = nodeList.length
    
    For index = 0 To length - 1 
    
      Set element = nodeList.item(index) 
    
      Wscript.Echo element.tagName 
    
    Next
    
    
    
    xmldoc.setProperty "SelectionNamespaces", "xmlns:xsl='http://www.w3.org/TR/REC-html40'"
    
    Set head = xmlDoc.selectSingleNode("//xsl:TITLE")
    
    Wscript.Echo head.tagName
    
    


    Thank you for your reply, Samuel!
    I believe your code is defenitely workable to get the wanted result, selectSingleNode and selectNodes can certainly work for this case.

    However, I'd like to know why getElementsByTagName doesn't work as expected-omit namespaces.
    Actually, my code above runs fine with MS XML 3.0. We have many legacy code written like that(using MS XML3.0), however, we find they no longer work after upgraded to MS XML 4.0 or higher.

    Monday, February 01, 2010 1:30 PM
  • The default query engine of MSXML4 and MSXML6 is XPath instead of XSL Pattern. As XPath is namespace aware, xmlDoc.getElementsByTagName("TITLE") will not find the node you want. So the best solution for MSXML is still XPath. getElementsByTagNameNS is another candidate suggested by W3C, unfortunately MSXML does not support DOM level 2 as for now.
    Monday, February 01, 2010 2:47 PM
  • Yes, I have been aware of the SelectionLanguage differences between MSXML3.0 with 4.0 or later.
    I have tested that with MSXML3.0, even I set the SelectionLanguage as XPath, getElementByTagName still succeed in my case, that's what really confusing me.
    Are there any other walkaround in MSXML 4 or later to omit default namespace(like getElementByTagName in MSXML 3) when doing query job?
    Monday, February 01, 2010 2:59 PM
  • Unfortunately SelectionLanguage in MSXML3 affects selectSingleNode and selectNodes but not getElementByTagName. You can neither specify the default namespace in getElementByTagName, nor omit default namespace in getElementByTagName as your TITLE element does have its namespace. Looks like XPath is the only way out, or push Microsoft to implement DOM level 2 with getElementsByTagNameNS support.
    • Marked as answer by RogerCui Wednesday, February 03, 2010 2:45 PM
    Monday, February 01, 2010 3:59 PM
  • The default query engine of MSXML4 and MSXML6 is XPath instead of XSL Pattern. As XPath is namespace aware, xmlDoc.getElementsByTagName("TITLE") will not find the node you want. So the best solution for MSXML is still XPath. getElementsByTagNameNS is another candidate suggested by W3C, unfortunately MSXML does not support DOM level 2 as for now.

    It's very valuable, Now I understand more about it, Thanks for your analysis!
    Saturday, August 28, 2010 11:14 PM