|
-
Jan 19th, 2011, 04:59 AM
#1
Thread Starter
Hyperactive Member
[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".
-
Jan 19th, 2011, 06:05 AM
#2
Re: DOMDocument vs DOMDocument60 and selectSingleNode
Microsoft XML Team's WebLog
 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?
-
Jan 19th, 2011, 08:06 AM
#3
Thread Starter
Hyperactive Member
Re: DOMDocument vs DOMDocument60 and selectSingleNode
 Originally Posted by Milk
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
-
Jan 19th, 2011, 08:50 AM
#4
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.
-
Mar 7th, 2017, 01:16 PM
#5
Thread Starter
Hyperactive Member
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.
-
Feb 14th, 2023, 05:33 PM
#6
Junior Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|