The XmlLite library allows developers to build high-performance XML-based applications that provide a high degree of interoperability with other applications that adhere to the XML 1.0 standard. The primary goals of XmlLite are ease of use, performance, and standards compliance.
XmlLite is implemented as a DLL and follows a pull programming model. In a pull model, after your application initiates parsing, it calls methods repeatedly to retrieve, or pull, the next node. After retrieving a node, your application can look at the node, including its name, value, attributes, and more. As appropriate, the parser advances so that the next time the application retrieves a node, it gets the next one.
Both the XmlLite reader and writer use a stream object for reading and writing the XML.
After you have created a reader by calling CreateXmlReader, you attach the IStream object to the reader by calling the SetInput method. After you have created a writer by calling CreateXmlWriter, you attach the IStream object by calling the SetOutput method.
If you want to use a simple in-memory IStream implementation, you can use the function CreateStreamOnHGlobal. If you want to use an IStream implementation that reads from and to a text file, you can use SHCreateStreamOnFile.
XmlLite is not thread-safe. If you are writing a multi-threaded application, it is up to you to make sure that you use XmlLite in a thread-safe manner. For example, if one of your threads has called the method to retrieve the next node, and that method has not returned, you must programmatically prevent another thread from attempting to retrieve a node.
The IXmlReader does not provide APIs to access typed content. You can declare that an element is of a certain type, but you cannot retrieve that element as that specified data type. All values are returned as strings, and it is up to the application to convert to types other than string.
Because some errors are not recoverable and may lead to unexpected behavior in further processing, it is crucial that the application user inspect the error code (HRESULT) returned by each method call before proceeding.
The following IXmlReader methods return a string pointer: GetLocalName, GetNamespaceUri, GetPrefix, GetQualifiedName, and GetValue.
When calling these methods, be aware that the pointer is only valid until you move the reader to another node. When you move the reader to another node, XmlLite may reuse the memory referenced by the pointer. Therefore, you should not use the pointer after calling one of the following methods: Read, MoveToNextAttribute, MoveToFirstAttribute, MoveToAttributeByName and MoveToElement. Although they do not move the reader, the following two methods will also make the pointer invalid: SetInput and IUnknown.Release. If you want to preserve the value that was returned in the string, you should make a deep copy.
For more information, read the full XmlLite Reader Programming Overview: http://msdn.microsoft.com/en-us/library/ms753140(VS.85).aspx
' ########################################################################################
' Microsoft Windows
' File: EX_XmlLite_01.bas
' Contents: XmlLite example
' The following example demonstrates how to parse an XML file using XmlLite.
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
' CSED_PBCC - Use the console compiler
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "shlwapi.inc"
#INCLUDE ONCE "ocidl.inc"
#INCLUDE ONCE "xmllite.inc"
FUNCTION PBMAIN () AS LONG
LOCAL hr AS LONG
' // Open read-only input stream
LOCAL pFileStream AS IStream
hr = SHCreateStreamOnFile("books.xml", %STGM_READ, pFileStream)
IF FAILED(hr) THEN
STDOUT "SHCreateStreamOnFile error &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Create the reader
LOCAL pReader AS IXmlReader
hr = CreateXmlReader($IID_IXmlReader, pReader, NOTHING)
IF FAILED(hr) THEN
STDOUT "CreateXmlReader error &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Set the DtdProcessing_Prohibit property
hr = pReader.SetProperty(%XmlReaderProperty_DtdProcessing, %DtdProcessing_Prohibit)
IF FAILED(hr) THEN
STDOUT "IXmlReader.SetProperty error &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Set the input source of the XML document to be parsed
hr = pReader.SetInput(pFileStream)
IF FAILED(hr) THEN
STDOUT "IXmlReader.SetInput error &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
LOCAL nodeType AS LONG
LOCAL pwszPrefix AS DWORD
LOCAL cwchPrefix AS DWORD
LOCAL pwszLocalName AS WSTRINGZ PTR
LOCAL pwszValue AS WSTRINGZ PTR
LOCAL nCount AS LONG
' // Parse the xml file
DO
hr = pReader.Read(nodeType)
IF hr <> %S_OK THEN EXIT DO
SELECT CASE AS LONG nodeType
CASE %XmlNodeType_XmlDeclaration
STDOUT "XmlDeclaration"
CASE %XmlNodeType_Element
IF pReader.IsEmptyElement THEN
STDOUT "Empty"
ELSE
hr = pReader.GetLocalName(pwszLocalName)
IF FAILED(hr) THEN
STDOUT "Error getting local name &H" & HEX$(hr)
ELSE
IF pwszLocalName THEN STDOUT "Element: " & @pwszLocalName
END IF
END IF
CASE %XmlNodeType_EndElement
IF pReader.IsEmptyElement THEN
STDOUT "Empty"
ELSE
hr = pReader.GetLocalName(pwszLocalName)
IF FAILED(hr) THEN
STDOUT "Error getting local name &H" & HEX$(hr)
ELSE
IF pwszLocalName THEN STDOUT "Element: " & @pwszLocalName
END IF
END IF
CASE %XmlNodeType_Text
hr = pReader.GetValue(pwszValue)
IF FAILED(hr) THEN
STDOUT "Error getting value &H" & HEX$(hr)
ELSE
IF pwszValue THEN STDOUT "Text: " & @pwszValue
END IF
END SELECT
LOOP
WAITKEY$
END FUNCTION
books.xml
<?xml version="1.0"?>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications
with XML.</description>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
<description>A former architect battles corporate zombies,
an evil sorceress, and her own childhood to become queen
of the world.</description>
</book>
<book id="bk103">
<author>Corets, Eva</author>
<title>Maeve Ascendant</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-11-17</publish_date>
<description>After the collapse of a nanotechnology
society in England, the young survivors lay the
foundation for a new society.</description>
</book>
<book id="bk104">
<author>Corets, Eva</author>
<title>Oberon's Legacy</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-03-10</publish_date>
<description>In post-apocalypse England, the mysterious
agent known only as Oberon helps to create a new life
for the inhabitants of London. Sequel to Maeve
Ascendant.</description>
</book>
<book id="bk105">
<author>Corets, Eva</author>
<title>The Sundered Grail</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2001-09-10</publish_date>
<description>The two daughters of Maeve, half-sisters,
battle one another for control of England. Sequel to
Oberon's Legacy.</description>
</book>
<book id="bk106">
<author>Randall, Cynthia</author>
<title>Lover Birds</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-09-02</publish_date>
<description>When Carla meets Paul at an ornithology
conference, tempers fly as feathers get ruffled.</description>
</book>
<book id="bk107">
<author>Thurman, Paula</author>
<title>Splish Splash</title>
<genre>Romance</genre>
<price>4.95</price>
<publish_date>2000-11-02</publish_date>
<description>A deep sea diver finds true love twenty
thousand leagues beneath the sea.</description>
</book>
<book id="bk108">
<author>Knorr, Stefan</author>
<title>Creepy Crawlies</title>
<genre>Horror</genre>
<price>4.95</price>
<publish_date>2000-12-06</publish_date>
<description>An anthology of horror stories about roaches,
centipedes, scorpions and other insects.</description>
</book>
<book id="bk109">
<author>Kress, Peter</author>
<title>Paradox Lost</title>
<genre>Science Fiction</genre>
<price>6.95</price>
<publish_date>2000-11-02</publish_date>
<description>After an inadvertant trip through a Heisenberg
Uncertainty Device, James Salway discovers the problems
of being quantum.</description>
</book>
<book id="bk110">
<author>O'Brien, Tim</author>
<title>Microsoft .NET: The Programming Bible</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-09</publish_date>
<description>Microsoft's .NET initiative is explored in
detail in this deep programmer's reference.</description>
</book>
<book id="bk111">
<author>O'Brien, Tim</author>
<title>MSXML3: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>36.95</price>
<publish_date>2000-12-01</publish_date>
<description>The Microsoft MSXML3 parser is covered in
detail, with attention to XML DOM interfaces, XSLT processing,
SAX and more.</description>
</book>
<book id="bk112">
<author>Galos, Mike</author>
<title>Visual Studio 7: A Comprehensive Guide</title>
<genre>Computer</genre>
<price>49.95</price>
<publish_date>2001-04-16</publish_date>
<description>Microsoft Visual Studio 7 is explored in depth,
looking at how Visual Basic, Visual C++, C#, and ASP+ are
integrated into a comprehensive development
environment.</description>
</book>
</catalog>
This example provides details of how to read an XML document by using XmlLite.
' ########################################################################################
' Microsoft Windows
' File: EX_XmlLiteReader.bas
' Contents: XmlLite example
' This example provides details of how to read an XML document by using XmlLite.
' Compilers: PBWIN 10+, PBCC 6+
' Headers: Windows API headers 2.03+
' Copyright (c) 2011 José Roca. Freeware. Use at your own risk.
' Portions Copyright (c) Microsoft Corporation. All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
' CSED_PBCC - Use the console compiler
#COMPILE EXE
#DIM ALL
#INCLUDE ONCE "shlwapi.inc"
#INCLUDE ONCE "ocidl.inc"
#INCLUDE ONCE "xmllite.inc"
' ========================================================================================
' Display the attributes
' ========================================================================================
FUNCTION WriteAttributes (BYVAL pReader AS IXmlReader) AS LONG
LOCAL hr AS LONG
LOCAL pwszPrefix AS WSTRINGZ PTR
LOCAL pwszLocalName AS WSTRINGZ PTR
LOCAL pwszValue AS WSTRINGZ PTR
hr = pReader.MoveToFirstAttribute
IF hr = %S_FALSE THEN
FUNCTION = hr
EXIT FUNCTION
END IF
IF hr <> %S_OK THEN
STDOUT "Error moving to first attribute &H" & HEX$(hr)
FUNCTION = -1
END IF
DO
IF ISFALSE pReader.IsDefault THEN
hr = pReader.GetPrefix(pwszPrefix)
IF FAILED(hr) THEN
STDOUT "Error getting prefix &H" & HEX$(hr)
hr = -1
EXIT DO
END IF
hr = pReader.GetLocalName(pwszLocalName)
IF FAILED(hr) THEN
STDOUT "Error getting local name &H" & HEX$(hr)
hr = -1
EXIT DO
END IF
hr = pReader.GetValue(pwszValue)
IF FAILED(hr) THEN
STDOUT "Error getting value &H" & HEX$(hr)
hr = -1
EXIT DO
END IF
IF pwszPrefix THEN
STDOUT "Attr: " & @pwszPrefix & " " & @pwszLocalName
ELSE
STDOUT "Attr: " & @pwszLocalName & " " & @pwszValue
END IF
END IF
hr = pReader.MoveToNextAttribute
IF hr <> %S_OK THEN EXIT DO
LOOP
FUNCTION = hr
END FUNCTION
' ========================================================================================
' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN () AS LONG
LOCAL hr AS LONG
LOCAL pFileStream AS IStream
LOCAL nodeType AS LONG
LOCAL pwszPrefix AS WSTRINGZ PTR
LOCAL pwszLocalName AS WSTRINGZ PTR
LOCAL pwszValue AS WSTRINGZ PTR
LOCAL nCount AS LONG
' // Open read-only input stream
hr = SHCreateStreamOnFile("stocks.xml", %STGM_READ, pFileStream)
IF FAILED(hr) THEN
STDOUT "SHCreateStreamOnFile error &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Create the reader
LOCAL pReader AS IXmlReader
hr = CreateXmlReader($IID_IXmlReader, pReader, NOTHING)
IF FAILED(hr) THEN
STDOUT "CreateXmlReader error &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Set the DtdProcessing_Prohibit property
hr = pReader.SetProperty(%XmlReaderProperty_DtdProcessing, %DtdProcessing_Prohibit)
IF FAILED(hr) THEN
STDOUT "Error setting XmlReaderProperty_DtdProcessing &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Set the input source of the XML document to be parsed
hr = pReader.SetInput(pFileStream)
IF FAILED(hr) THEN
STDOUT "Error setting input for reader &H" & HEX$(hr)
WAITKEY$
EXIT FUNCTION
END IF
' // Parse the xml file
DO
hr = pReader.Read(nodeType)
IF hr <> %S_OK THEN EXIT DO
SELECT CASE AS LONG nodeType
CASE %XmlNodeType_XmlDeclaration
STDOUT "XmlDeclaration"
hr = WriteAttributes(pReader)
IF FAILED(hr) THEN
STDOUT "Error writing attributes &H" & HEX$(hr)
EXIT DO
END IF
CASE %XmlNodeType_Element
hr = pReader.GetPrefix(pwszPrefix)
IF FAILED(hr) THEN
STDOUT "Error getting prefix &H" & HEX$(hr)
EXIT DO
END IF
hr = pReader.GetLocalName(pwszLocalName)
IF FAILED(hr) THEN
STDOUT "Error getting local name &H" & HEX$(hr)
EXIT DO
END IF
IF pwszPrefix THEN
STDOUT "Element: " & @pwszPrefix & @pwszLocalName
ELSE
STDOUT "Element: " & @pwszLocalName & @pwszValue
END IF
hr = WriteAttributes(pReader)
IF FAILED(hr) THEN
STDOUT "Error writing attributes &H" & HEX$(hr)
EXIT DO
END IF
IF pReader.IsEmptyElement THEN
STDOUT "Empty"
END IF
CASE %XmlNodeType_EndElement
hr = pReader.GetPrefix(pwszPrefix)
IF FAILED(hr) THEN
STDOUT "Error getting prefix &H" & HEX$(hr)
EXIT DO
END IF
hr = pReader.GetLocalName(pwszLocalName)
IF FAILED(hr) THEN
STDOUT "Error getting local name &H" & HEX$(hr)
EXIT DO
END IF
IF pwszPrefix THEN
STDOUT "End element: " & @pwszPrefix & " " & @pwszLocalName
ELSE
STDOUT "End element: " & @pwszLocalName & " " & @pwszValue
END IF
hr = WriteAttributes(pReader)
IF FAILED(hr) THEN
STDOUT "Error writing attributes &H" & HEX$(hr)
EXIT DO
END IF
IF pReader.IsEmptyElement THEN
STDOUT "Empty"
END IF
CASE %XmlNodeType_Text, %XmlNodeType_Whitespace
hr = pReader.GetValue(pwszValue)
IF FAILED(hr) THEN
STDOUT "Error getting value &H" & HEX$(hr)
EXIT DO
END IF
IF pwszValue THEN STDOUT "Text: " & @pwszValue
CASE %XmlNodeType_CDATA
hr = pReader.GetValue(pwszValue)
IF FAILED(hr) THEN
STDOUT "Error getting value &H" & HEX$(hr)
EXIT DO
END IF
IF pwszValue THEN STDOUT "CDATA: " & @pwszValue
CASE %XmlNodeType_ProcessingInstruction
hr = pReader.GetLocalName(pwszLocalName)
IF FAILED(hr) THEN
STDOUT "Error getting local name &H" & HEX$(hr)
EXIT DO
END IF
hr = pReader.GetValue(pwszValue)
IF FAILED(hr) THEN
STDOUT "Error getting value &H" & HEX$(hr)
EXIT DO
END IF
IF pwszValue THEN STDOUT "Processing Instruction name: " & @pwszLocalName & " value " & @pwszValue
CASE %XmlNodeType_Comment
hr = pReader.GetValue(pwszValue)
IF FAILED(hr) THEN
STDOUT "Error getting value &H" & HEX$(hr)
EXIT DO
END IF
IF pwszValue THEN STDOUT "Comment: " & @pwszValue
CASE %XmlNodeType_DocumentType
STDOUT "DOCTYPE is not printed"
END SELECT
LOOP
WAITKEY$
END FUNCTION
' ========================================================================================
Stocks.xml
<?xml version="1.0"?>
<portfolio xmlns:dt="urn:schemas-microsoft-com:datatypes">
<stock exchange="nasdaq">
<name>new</name>
<symbol>zzzz</symbol>
<price>20.313</price>
</stock>
<stock exchange="nyse">
<name>zacx corp</name>
<symbol>ZCXM</symbol>
<price>28.875</price>
</stock>
<stock exchange="nasdaq">
<name>zaffymat inc</name>
<symbol>ZFFX</symbol>
<price>92.250</price>
</stock>
<stock exchange="nasdaq">
<name>zysmergy inc</name>
<symbol>ZYSZ</symbol>
<price>20.313</price>
</stock>
</portfolio>