Basic Search  Advanced Search   
Topics Resources Free Library Software XML News About Us
  You are here: home Info Bank Articles » XML & Binary Data Saturday, 23 February 2008

Back to Articles Page      


XML and Binary Data
(Updated to use MSXML 4.0)

  • Introduction
    XML, or eXtensible Markup Language, is a method for putting structured data in a text file. Structured data refers to data that is tagged for its content, meaning, or use. To better understand, let's look at a XML document that describes a bank account:
    XML Sample
    In this XML document, each custom tag explicitly identifies the kind of information, for example <Balance> tag identifies the money I have in my bank account (don't trust above XML document!), <OpenDate> tag identifies the date on which account was opened, and so on. HTML is used to tell how to present the document, but XML is used to describe structure and content of the document.

    XML solves varieties of problems. Keep in mind that XML is not only for web. It can be used for virtually any kind of application - depends on your imagination. It's best suited to pass data across machines running different platform/operating system, because everybody understands plain text

    But what if, part of your document is not text; it is binary, for instance, an image? Does XML answer this question? The answer is yes, and in this article I'll show you how to pass binary data as part of XML document and we will learn this by passing a signature image file associated with each bank account, as an example.

  • The Answer
    To send the binary data as part of XML document, it needs to be encoded using Base64 encoding scheme.

    Base64 encoding, specified in RFC 2045 - MIME (Multipurpose Internet Mail Extensions) uses a 64-character subset (A-Za-z0-9+/) to represent binary data and = for padding. Base64 processes data as 24-bit groups, mapping this data to four encoded characters. It is sometimes referred to as 3-to-4 encoding. Each 6 bits of the 24-bit group is used as an index into a mapping table (the base64 alphabet) to obtain a character for the encoded data. According to the MIME specification the encoded data has line lengths limited to 76 characters, but this line length restriction does not apply when transmitting binary data as part of XML document.
  • The Solutions
    Binary data to base64 encoding and back can be done in many ways. We can write our own COM DLL that exposes methods to encode and decode the data and then call that DLL from our ASP code/JScript code. Microsoft ships a sample, which highlights sample base64 encoding and decoding. Have a look at Q191239 (External link;EN-US;q191239). Also, Microsoft SOAP Toolkit (External link has a base64 encoder/decoder.

    You can also use the Microsoft XML Core Services (MSXML) to do base64 encoding and decoding. We'll use MSXML 4.0 in this article.

  • An Example: Signature image as part of a XML document
    It's now time to look at an example and see how actually the binary data gets transmitted as part of XML document. In this example, we have:
  • A Microsoft Access 2000 database called "Accounts.mdb" having only one table with the name "AcctTable". This table has only one record with Signature field having a binary GIF image data.
  • An ASP File, getAcctDetails.asp, which connects to Accounts database and generates the XML document from the RecordSet. In this ASP file, you'll see how we are converting binary data into base64 encoding.
  • A Visual Basic Project, XMLBin.vbp, which loads the XML file having base64 encoded binary image and saves that image onto disk as a GIF file. Here we'll learn how to decode base64 data back to binary.

Here's how the Microsoft Access 2000 database record looks:

Access Database
Let's now have a closer look at the ASP file, getAcctDetails.asp. This ASP file connects to the database and generates XML for the record using MSXML4.DLL.
Here is part of the ASP file:

	'Connect to the database
	Set connDB = Server.CreateObject("ADODB.Connection")
	connDB.Provider = "Microsoft.Jet.OLEDB.4.0"
	connDB.Open Server.Mappath(".") & "\Accounts.mdb"

	'Get the data
	SQLStmt = 	"SELECT * FROM AcctTable WHERE Number = " & sAccountNumber
	Set rsResult = connDB.Execute(SQLStmt)

	'Create the XML DOMDocument
	Set xmlDOMDocument = Server.CreateObject("Msxml2.DOMDocument.4.0")
	xmlDOMDocument.loadXML "<BANKACCOUNT />"

	Set oRoot = xmlDOMDocument.documentElement 
	If Not rsResult.EOF Then
		'For each field create the element and set it's value = field's value
	    Set oElement = xmlDOMDocument.createElement("NUMBER")
	    oElement.nodeTypedValue = CStr(rsResult.Fields("Number").Value)
	    oRoot.appendChild oElement
	    'Here comes the Binary data part
	    Set oElement = xmlDOMDocument.createElement("SIGNATURE")
	    oElement.dataType = "bin.base64"
	    oElement.nodeTypedValue = rsResult.Fields("Signature").Value
	    oRoot.appendChild oElement
	    Set oElement = xmlDOMDocument.createElement("ERROR")
	    oElement.nodeTypedValue = "Account number [" & sAccountNumber & "] not found."
	    oRoot.appendChild oElement
	End If

	'Write (Save) the generated XML document to the stream. Response
	'Do clean up
This ASP File expects Account Number as parameter and stores its value in sAccountNumber variable. The ASP File runs the SQL statement to get the account record details. We then create Msxml2.DOMDocument.4.0 object and add BANKACCOUNT as root node. Each field in the table is then added as a child node to BANKACCOUNT root node. The important code here is: oElement.dataType = "bin.base64"
oElement.nodeTypedValue = rsResult.Fields("Signature").Value

When we specify NodeElement.dataType as bin.bae64, MSXML4.DLL internally converts binary data (assigned to NodeElement.nodeTypedValue) to base64.

Save this ASP file in a IIS virtual directory and run it from the browser as http://localhost/binary/getAcctDetails.asp?AcctNo=1234. You should see:

XML file as seen in IE

Now, click on View | Source in the Internet Explorer browser and save the source text as .XML file (c:\test.xml). Note the contents of SIGNATURE tag, it is the base64-encoded form of binary image stored in the database.

So, we saw how MSXML4.DLL converts binary to base64. Let's use it again to do the conversion the other way - base64 to binary conversion.

We have a tiny Visual Basic Application with only two edit boxes, where we specify the names of input XML file and output .GIF file. The input XML file should have above XML structure. The Visual Basic application loads the XML file, and then reads the content of BANKACCOUNT\SIGNATURE node, and saves it as a binary image .GIF file. Again, we use MSXML4.DLL to do all these.

Here is how Visual Basic application looks like:

VB Application

Here is the code for the Visual Basic Application:
	Dim oXMLDOMDoc As New MSXML2.DOMDocument40
	Dim oNode As MSXML2.IXMLDOMNode
	oXMLDOMDoc.async = False

	'Load the XML document that contains binary data (as base64 encoded)    
	If oXMLDOMDoc.Load(txtInputXMLFile.Text) Then
		'Get the node (Signature) that contains binary data
	    Set oNode = oXMLDOMDoc.selectSingleNode("BANKACCOUNT/SIGNATURE")
	    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 txtOutputImageFile.Text For Binary As #1
	    Put #1, 1, btArr
	    Close #1

	    Set oXMLDOMDoc = Nothing
	    Set oNode = Nothing
	    MsgBox "Signature saved into the gif file with the name " & txtOutputImageFile.Text
		'XML document load error!
	    MsgBox "Error: " & oXMLDOMDoc.parseError.reason
	End If

	'End the application

To run this application: open the Visual Basic project, click on Project | References, and check "Microsoft XML, version 4".

Above code loads the XML file; selects BANKACCOUNT/SIGNATURE node and gets the binary data using oNode.nodeTypedValue. This is the place where MSXML4.DLL automatically converts base64 data to binary data. Try to open the output .GIF file and you should see my signature.

  • Summary
    XML document is a well-formed text document. To send binary data as part of this XML document, we need to make use of base64 encoding. In this article we saw how we can use MSXML4.DLL for base64 encoding/decoding to transfer binary data as part of XML document.

  • Download source code for this article. [12KB]

    If you have any questions/comments, feel free to send mail to

  • References

  • External linkXML, SOAP and Binary Data
    External linkMicrosoft KB Article: Sample Base 64 Encoding and Decoding
    External Intuition and Binary XML
    External Handling Binary Data in XML Documents
    External linkMicrosoft KB Article: HOWTO: Create XML Documents with Binary Data in Visual Basic

  • Author's Notes

    • The base64 character set is: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'. MSXML 2.0a (5.00.2314.1000, 490 KB [502, 544 bytes]) has a bug related to Base64 encoding/decoding. Instead of a / (forward slash) it uses an asterisk (*). This bug has been fixed in MSXML 3.0.

    • A reated useful KB article: Q296772: Send a Binary Stream by Using XMLHTTP
      In some cases you may want to send a binary stream to a server. One way to do so is to use the IXMLHTTPRequest object. This article demonstrates how to retrieve an ADO recordset from a server, modify it, and send it back as a stream of binary data.

    • Related KB Article: HOWTO: Create XML Documents with Binary Data in Visual Basic


    Back to Articles Page      

    All information on this site is for training only. We do not warrant its correctness or its fitness to be used. The risk of using it remains entirely with the user.


      Contact Us | E-mail Us | Site Guide | About PerfectXML | Advertise ©2004 All rights reserved. | Privacy