nodeTypedValue and dataType are part of Microsoft's extension to W3C DOM; W3C DOM does not define these properties. And we think that it is not possible to create an XSD that can be used to validate XML document that contains MSXML created base64 node. It might be possible with XDR schema.
The alternative we would suggest is to use XSD schema to validate, while remove the xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64" attribute from the source XML document (programmatically or manually), and then set the dataType property before you read the element using nodeTypedValue. May be you can write supporting functions such as getAttributeValue and getBinaryAttributeValue, and have the later method set the dataType property to "bin.base64" before using nodeTypedValue.
Let's look at an example:
Consider the sample XML document (c:\bank.xml)
<?xml version="1.0"?>
<BANKACCOUNT>
<NUMBER>1234</NUMBER>
<TYPE>Checking</TYPE>
<OPENDATE>11/4/74</OPENDATE>
<SIGNATURE >R0lGODdhZAAeAPcAAAAAAICAgIAAAICAAACAAACAgAAAgIAAgICAQABAQACA/wBAgEAA/4BA
AP///8DAwP8AAP//AAD/AAD//wAA//8A////gAD/gID//4CA//8AgP+AQAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAABkAB4AAAj/AB0IHEiwoMGD
CBMqXMiwocOHECNKnEixosWLGDNq3Mixo8ePIEOKHEmypEABH1Ga1CigZcuOKlcqfNlQpUuW
MmfGZLiT5sWdOU/6dAgUKEWjK4dCLJoRKUmlEZlidCoSqlCqA41idXCzoMuuB7+GBVtzJley
Xg2i/NoTLVeCMbv2VHuS6Na5CLW+zZrV6lyaL4sC5stz61nCYdUK7qtU7tC1aW0i3ps2r9jB
eSPTlTt27V/NPuMurkw5cF3LfSlPPmyZqWvVnr06xVxXbMK4kx/jhav18dvPcBcGxk1UKOOb
kmWn1nv2svLUhUs/jG1WNV/OpOneJs5bMtvpVlHzN1Y8fft47dYLu1W/Pn1Um8ibe04eFCRY
76up129qO/hv6rYZth9/gwk4YEjJzWfggRwFuGBCAQEAOw==</SIGNATURE>
</BANKACCOUNT>
And here is the XSD Schema (c:\bank.xsdthat can be used to validate the above XML document:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xs:element name="BANKACCOUNT">
<xs:complexType >
<xs:sequence>
<xs:element name="NUMBER" type="xs:int"/>
<xs:element name="TYPE" type="xs:string"/>
<xs:element name="OPENDATE"/>
<xs:element name="SIGNATURE"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Note that we have removed the xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64" attribute from the source XML document and hence not defined in the XSD schema as well.
The following Visual basic code illustrates that even if xmlns:dt="ur... attribute is missing in the source XML document, we can still retrieve the binary data by setting the dataType property.
Option Explicit
Private Sub Form_Load()
Dim objXMLDoc As New MSXML2.DOMDocument40
Dim objSchemaCache As New MSXML2.XMLSchemaCache40
Dim validationError As MSXML2.IXMLDOMParseError
Dim oNode As MSXML2.IXMLDOMNode
objXMLDoc.async = False
objXMLDoc.validateOnParse = False
If objXMLDoc.Load("c:\bank.xml") Then
objSchemaCache.Add "", "c:\bank.xsd"
Set objXMLDoc.schemas = objSchemaCache
Set validationError = objXMLDoc.Validate
If validationError.errorCode = 0 Then
MsgBox "XML Document is valid according to the schema"
Set oNode = objXMLDoc.selectSingleNode("/BANKACCOUNT/SIGNATURE")
If Not oNode Is Nothing Then
MsgBox "Signature node is of type: " & oNode.dataType
'The following line is important
oNode.dataType = "bin.base64"
MsgBox "Signature node is NOW of type: " & oNode.dataType
Dim btArr() As Byte
'Load the binary data into an Byte Array
btArr = oNode.nodeTypedValue
'Save the byte array into a file opened in binary mode
Open "c:\signature.gif" For Binary As #1
Put #1, 1, btArr
Close #1
MsgBox "Signature saved as c:\signature.gif"
Else
MsgBox "Signature node not found!"
End If
Else
MsgBox validationError.reason & vbNewLine & "Line: " & validationError.Line
End If
Else
MsgBox objXMLDoc.parseError.reason & vbNewLine & "Line: " & objXMLDoc.parseError.Line
End If
Unload Me
End Sub
If you have the XML and XSD files saved as c:\bank.xml and c:\bank.xsd, that above code validates the source XML document c:\bank.xml using the XSD schema c:\bank.xsd and reads the Signature node and saves the binary data (.gif image) into a file named c:\signature.gif.
|