perfectxml.com
 Basic Search  Advanced Search   
Topics Resources Free Library Software XML News About Us
home » focus » msxml » ask a question » past questions & answers Monday, 13 August 2007
 
NEWS
MSXML 4.0 SP2 now available!

 
MSXML
Basics
DOM
SAX
XPath
XSLT
Schemas
SOM
HTTP Access
.NET
Data Islands
Ask a Question
   Past Q&As
C++ Samples
DLL/Version Info
Reference Guide
Books
KB Articles
   HOW TO
   SAMPLE
   INFO
   BUG/PRB
   FIX
   Misc.
MSXML Tips
   August 2002
   September 2002
MSXML Tools

Microsoft XML Core Services


Go back to list of previously asked questions and answers

Question: I have an XML document that contains binary data in the base64 encoded format. I create this binary data node using MSXML and hence it adds the xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64" attribute to this binary node.

Now, when I try to validate this XML document using XSD schema, I get the error "The attribute '{urn:schemas-microsoft-com:datatypes}dt' on this element is not defined in the DTD/Schema".

If I remove the xmlns:dt="ur... attribute, the validation succeeds, but then MSXML nodeTypedValue does not recognize the data as binary, it treats it as a string, and hence I am not able to get back the binary data from the base64 encoded value. Is there a way that I can validate the XML document, and still get back the binary node value.
Asked By: Steve
Viewed: 5719
Answer: 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.


Go back to list of previously asked questions and answers
  Contact Us | E-mail Us | Site Guide | About PerfectXML | Advertise ©2004 perfectxml.com. All rights reserved. | Privacy