About XmlLite

Started by José Roca, August 21, 2011, 12:14:10 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

José Roca

 
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

José Roca


' ########################################################################################
' 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>


José Roca

 
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>