Results 1 to 6 of 6

Thread: [RESOLVED] DOMDocument vs DOMDocument60 and selectSingleNode

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Mar 2009
    Posts
    244

    Resolved [RESOLVED] DOMDocument vs DOMDocument60 and selectSingleNode

    Well I'm having this weird problem (at least from a logical perspective).
    I have the following XML which I have saved as "C:\MyResponse.xml":
    Code:
    <PensioenaangifteResponse Versie="2010.1.0" xmlns="http://www.pensioenaangifte.nl/schemas/PensioenaangifteResponse/2010/1/0">
    	<BerichtId>MyBerichtId</BerichtId>
    	<BerichtType>Bevestiging</BerichtType>
    	<Identificatie>
    		<UwKenmerk>MyUwKenmerk</UwKenmerk>
    		<OnsKenmerk>MyOnsKenmerk</OnsKenmerk>
    		<DatumTijdOntvangst>2011-01-19T10:31:06</DatumTijdOntvangst>
    	</Identificatie>
    </PensioenaangifteResponse>

    Now I read it back using the following code (for testing purposes, see further down):

    Code:
      Dim doc60 As DOMDocument60
      Dim nod As IXMLDOMNode
      Set doc60 = New DOMDocument60
      If doc60.Load("C:\MyResponse.xml") Then
        Set nod = doc60.selectSingleNode("PensioenaangifteResponse")
      End If
    the file get's read but nod is Nothing after the doc60.selectSingleNode, so it can't find the node PensioenaangifteResponse.
    Now I have the following code:
    Code:
      Dim doc As DOMDocument
      Dim nod As IXMLDOMNode
      Set doc = New DOMDocument
      If doc.Load("C:\MyResponse.xml") Then
        Set nod = doc.selectSingleNode("PensioenaangifteResponse")
      End If
    the file get's read and nod is loaded after the doc.selectSingleNode, so it has found the node PensioenaangifteResponse.

    What the hell is going on? DOMDocument60 for some reason can't find the node, but using DOMDocument the node is found..

    This is all a test (with loading the xml from a file), as the original is not a file but a response returned by XMLHTTP60.responseXML which is a DOMDocument60 (a SoapEnvelop with the XML as a part of it)..
    My original code just uses the node directly from the SoapEnvelope node, which first used to work perfectly up until the server started to send the namespace in this XML part as a default namespace xmlns="http://www.pensioenaangifte.nl/schemas/PensioenaangifteResponse/2010/1/0" instead of the previous namespace xmlns:ns1="http://www.pensioenaangifte.nl/schemas/PensioenaangifteResponse/2010/1/0".

  2. #2
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: DOMDocument vs DOMDocument60 and selectSingleNode

    Microsoft XML Team's WebLog
    Quote Originally Posted by The Weblog
    Security Migration – Understanding Off-By-Default
    In MSXML 6.0 several security sensitive properties have been configured to be off by default. When upgrading these properties may need to be re-enabled, however be aware that these properties are important in securing the DOM and SAX Reader when parsing data from untrusted or unauthenticated clients. The security risks should be carefully considered when enabling these properties in an unauthenticated channel.
    I don't much about this but could the above be have anything to do with it? Is there some property you need to set to true?
    W o t . S i g

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Mar 2009
    Posts
    244

    Re: DOMDocument vs DOMDocument60 and selectSingleNode

    Quote Originally Posted by Milk View Post
    Microsoft XML Team's WebLog

    I don't much about this but could the above be have anything to do with it? Is there some property you need to set to true?
    I think they are referring to the property resolveExternals which is False on DOMDocument60 and True on DOMDocument.

    It seems they changed the way selectSingleNode works between DOMDocuments, which is very annoying as there is no real documentation on the change. It seems with DOMDocument60 you have to use prefixes, unless the XML itself has it's namespace already prefixed. I can't understand which moron comes up with a change like that, if I want the first node called 'MyNode' then just give it back to me and not let me have to deal with unnecessary prefixing unless I specifically use prefixes. (especially because it does work if the XML itself already has the namespace prefixed (xmlns:blah="..") instead of a default namespace (xmlns="")).
    Code:
    <MyXML xmlns:blah="http://myserver.com/myschema">
       <MyValue>value</MyValue>
    </MyXML>
    with above example nod.selectSingleNode("MyValue") does work on a DOMDocument60

    Code:
    <MyXML xmlns="http://myserver.com/myschema">
       <MyValue>value</MyValue>
    </MyXML>
    but with above example nod.selectSingleNode("MyValue") fails on a DOMDocument60

    both are valid XML's against the same XSD, but require a different approach in handling them, which IMHO is a big design flaw no matter what reasons the designers have for the change.
    As I said, selectSingleNode("MyValue") should work in both cases and should always return the first Node that corresponds to my request.

    So for the time being I'll just transform the given node to a DOMDocument, instead of having to deal with unnecessary namespaces.
    example:
    Code:
      Dim doc As DOMDocument
      Dim nodRoot As IXMLDOMNode
      Dim nodElement As IXMLDOMNode
    
      Set doc = New DOMDocument
      doc.resolveExternals = False
      If doc.LoadXML(nodOriginalNodeFromDOMDocument60.XML) Then
        Set nodRoot = doc.selectFirstNode("MyXML")
        If Not nodRoot Is Nothing Then
           Set nodElement = nodRoot.selectFirstNode("MyValue")
           If Not nodElement Is Nothing Then
             Call MsgBox("MyValue=" & nodElement.Text)
           End If
           Set nodElement = Nothing
        End If
        Set nodRoot = Nothing
      End If
      set doc = Nothing

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: DOMDocument vs DOMDocument60 and selectSingleNode

    I don't know about "no real documentation" on this.

    Example:
    Code:
    Option Explicit
    
    'Two buttons:           cmdDOMDocument
    '                       cmdDOMDocument60
    '
    'One multiline textbox: Text1
    
    Private Const XML_FILE As String = "MyResponse.xml"
    
    Private Sub Log(Optional ByVal Text As String)
        Text1.SelText = Text & vbNewLine
    End Sub
    
    Private Sub cmdDOMDocument_Click()
        Dim doc As DOMDocument
        Dim nod As IXMLDOMNode
        
        Log "DOMDocument"
        Set doc = New DOMDocument
        Log vbTab & "SelectionLanguage=" & doc.getProperty("SelectionLanguage")
        If doc.Load(XML_FILE) Then
            Set nod = doc.selectSingleNode("PensioenaangifteResponse")
            Log vbTab & "nod Is " & TypeName(nod)
        Else
            Log vbTab & "Load failed!"
        End If
        Log
    End Sub
    
    Private Sub cmdDOMDocument60_Click()
        Dim doc60 As DOMDocument60
        Dim nod As IXMLDOMNode
        
        Log "DOMDocument60"
        Set doc60 = New DOMDocument60
        Log vbTab & "SelectionLanguage=" & doc60.getProperty("SelectionLanguage")
        If doc60.Load(XML_FILE) Then
            Set nod = doc60.selectSingleNode("PensioenaangifteResponse")
            Log vbTab & "nod Is " & TypeName(nod)
        Else
            Log vbTab & "Load failed!"
        End If
        Log
    End Sub
    Result:
    Code:
    DOMDocument
    	SelectionLanguage=XSLPattern
    	nod Is IXMLDOMElement
    
    DOMDocument60
    	SelectionLanguage=XPath
    	nod Is Nothing
    Using the right version of MSXML [in Internet Explorer]:
    Default Query Language - When you are querying the DOM with SelectNodes or SelectSingleNode the default selection language in MSXML6 is XPath while the default selection language in MSXML3 is XSLPatterns. To switch MSXML3 to the standard XPath 1.0 query language set the second-level DOM property Selection Language like this:

    xmlDoc.setProperty("SelectionLanguage", "XPath");

    see our SDK for more details.

  5. #5

    Thread Starter
    Addicted Member
    Join Date
    Mar 2009
    Posts
    244

    Angry Re: DOMDocument vs DOMDocument60 and selectSingleNode

    Came across this problem again (but with another XML, funny enough, also a newer version of the XML), and found my own question here.
    As far as I can see the only solution to this:

    Code:
       
      Dim doc60 As DOMDocument60
      Dim nod As IXMLDOMNode
      Set doc60 = New DOMDocument60
      If doc60.Load("C:\MyResponse.xml") Then
        Call doc60.setProperty("SelectionNamespaces", "xmlns:pr=""http://www.pensioenaangifte.nl/schemas/PensioenaangifteResponse/2010/1/0""")
        Set nod = doc60.selectSingleNode("pr:PensioenaangifteResponse")
      End If
    The problem is a default namespace without a prefix in the original XML..
    So you have to add the namespace yourself WITH a prefix through setProperty("SelectionNamespaces", ...).
    It sucks to have to do it like this, add your own prefix and having to use it, but it seems to be the only way to get around it.
    Or write your own selectSingleNode which loops through the node and compares it to the baseName.

    Edit: But another crap thing is, if they ever add their own prefix and it's different from the one you had set, then you're screwed...... Man why would they make it easy........ crap design.

    Edit2: damn, I found I 'fixed' it originally by just using DOMDocument instead of DOMDocument60 and had in comment "if you want to use DOMDocument60 you'll have to use doc.selectSingleNode("//*[local-name()='<NodeNameYouWant>']")

    Code:
       
      Dim doc60 As DOMDocument60
      Dim nod As IXMLDOMNode
      Set doc60 = New DOMDocument60
      If doc60.Load("C:\MyResponse.xml") Then
        Set nod = doc60.selectSingleNode(""//*[local-name()='PensioenaangifteResponse']")
      End If
    Last edited by SuperDre; Mar 7th, 2017 at 01:59 PM.

  6. #6
    Junior Member
    Join Date
    Oct 2013
    Location
    California
    Posts
    16

    Re: DOMDocument vs DOMDocument60 and selectSingleNode

    "The problem is a default namespace without a prefix in the original XML..
    So you have to add the namespace yourself WITH a prefix through setProperty("SelectionNamespaces", ...)."

    Thank you so much for this solution. I tried so many things and had to create my own namespace, just like you indicated.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width