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:
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 (http://support.microsoft.com/default.aspx?scid=kb;EN-US;q191239). Also, Microsoft SOAP Toolkit (http://msdn.microsoft.com/downloads/default.asp?URL=/code/sample.asp?url=/msdn-files/027/001/580/msdncompositedoc.xml) 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:
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)
'Here comes the Binary data part
Set oElement = xmlDOMDocument.createElement("SIGNATURE")
oElement.dataType = "bin.base64"
oElement.nodeTypedValue = rsResult.Fields("Signature").Value
Set oElement = xmlDOMDocument.createElement("ERROR")
oElement.nodeTypedValue = "Account number [" & sAccountNumber & "] not found."
'Write (Save) the generated XML document to the stream.
'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:
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:
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
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 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.
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.
Downloadsource code for this article. [12KB]
If you have any questions/comments, feel free to send mail to .
XML, SOAP and Binary Data
Microsoft KB Article: Sample Base 64 Encoding and Decoding
XML.com: Intuition and Binary XML
XML.com: Handling Binary Data in XML Documents
Microsoft 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.