xHarbour Reference Documentation > Class Reference (textmode) xHarbour Developers Network  

TXmlDocument()

Creates a new TXmlDocument object.

Syntax

TXmlDocument():new( [<nFileHandle>|<cXmlString>], [<nStyle>] ) --> oTXmlDocument

Arguments

<nFileHandle>
This is a file handle of an XML file to read. It is returned from function FOpen().
<cXmlString>
Instead of a file handle, an XML formatted character string can be passed. If the first parameter is omitted, the object has no XML data, but can be used to add XML nodes and create a new XML file (see example).
<nStyle>
This parameter instructs the TXMlDocument object how to read an XML file and/or how to write XML nodes into a file. #define constants listed in Hbxml.ch are used to specify <nStyle>:

Constants for XML object creation
ConstantValueDescription
HBXML_STYLE_INDENT1Indents XML nodes with one space
HBXML_STYLE_TAB2Indents XML nodes with tabs
HBXML_STYLE_THREESPACES4Indents XML nodes with three spaces
HBXML_STYLE_NOESCAPE8Reads and creates unescaped characters
  in data sections

Note:  when the style HBXML_STYLE_NOESCAPE is set, the textual content enclosed in an opening and closing XML tag is scanned for characters that normally must be escaped in XML. This can lead to a considerable longer time for reading the XML data.

The characters to be escaped are single and double quotes ('"), ampersand (&), and angled brackets (<>). If such characters exist in textual content and are not escaped, a parsing error is generated, unless HBXML_STYLE_NOESCAPE is used.

Return

Function TXmlDocument() creates the object and method :new() initializes it.

Description

The TXmlDocument() class provides objects for reading and creating XML files. XML stands for eXtensible Markup Language which is similar to HTML, but designed to describe data rather to display it. To learn more about XML itself, the internet provides very good free online tutorials. The website www.w3schools.com is is a good place to quickly learn the basics on XML.

A TXmlDocument object maintains an entire XML document and builds from it a tree of TXmlNode() objects which contain the actual XML data. The first XML node is stored in the :oRoot instance variable, which is the root node of the XML tree. Beginning with the root node, an XML document can be traversed or searched for particular data. The classes TXmlIteratorScan() and TXmlIteratorRegEx() are available to find a particular XML node, based on its tag name, attribute or data it contains.

Instance variables

:oRoot
Root node of the XML tree.
:nStatus
Status information on XML parsing.
:nError
Error code for XML parsing.
:nLine
Current line number being parsed.
:oErrorNode
TXmlNode object containing illegal XML code.
:nNodeCount
Number of nodes in the XML tree.

Methods for XML data manipulation

:read( ... ) --> self
Reads an XML file or string.
:toString( <nStyle> ) --> cXmlString
Creates an XML formatted character string.
:write( <nFileHandle>, [<nStyle>] ) --> self
Creates an XML formatted character string.

Methods for searching and navigating

:findFirst( ... ) --> oTXmlNode | NIL
Locates the first XML node containing particular data.
:findFirstRegEx( ... ) --> oTXmlNode
Locates the first XML node containing particular data using regular expressions.
:findNext() --> oTXmlNode | NIL
Finds the next XML node matching a search criteria.

Info

See also:TXmlIterator(), TXmlIteratorRegEx(), TXmlIteratorScan(), TXmlNode()
Category: Object functions , xHarbour extensions
Header:hbxml.ch
Source:rtl\txml.prg
LIB:xhb.lib
DLL:xhbdll.dll

Examples

Creating an XML file

// The example uses the Customer database and creates an XML file
// from it. The database structure and its records are written
// to different nodes in the XML file. The basic XML tree is this:
//
// <database>
//  <structure>
//   <field .../>
//  </structure>
//  <records>
//   <record>
//    <fieldname> data </fieldname>
//   </record>
//  </records>
// </database>

   #include "hbXml.ch"

   PROCEDURE Main
      LOCAL aStruct, aField, nFileHandle
      LOCAL oXmlDoc, oXmlNode, hAttr, cData
      LOCAL OXmlDatabase, oXmlStruct, oXmlRecord, oXmlField

      USE Customer

      aStruct  := DbStruct()

      // Create empty XML document with header
      oXmlDoc  := TXmlDocument():new( '<?xml version="1.0"?>' )

      // Create main XML node
      oXmlDatabase := TXmlNode():new( , "database", { "name" => "CUSTOMER" } )
      oXmlDoc:oRoot:addBelow( oXmlDatabase )

      // copy structure information to XML
      oXmlStruct := TXmlNode():new( , "structure" )
      oXmlDataBase:addBelow( oXmlStruct )

      FOR EACH aField IN aStruct
         // store field information in XML attributes
         hAttr := { "name" => Lower( aField[1] ), ;
                    "type" => aField[2], ;
                    "len"  => LTrim( Str(aField[3]) ), ;
                    "dec"  => LTrim( Str(aField[4]) )  }

         oXmlField := TXmlNode():new(, "field", hAttr )
         oXmlStruct:addBelow( oXmlField )
      NEXT

      // copy all records to XML
      oXmlNode := TXmlNode():new( , "records" )
      oXmlDataBase:addBelow( oXmlNode )

      DO WHILE .NOT. Eof()
         hAttr      := { "id" => LTrim( Str( Recno() ) ) }
         oXmlRecord := TXmlNode():new( , "record", hAttr )

         FOR EACH aField IN aStruct
            IF aField[2] == "M"
               // Memo fields are written as CDATA
               cData     := FieldGet( Hb_EnumIndex() )
               oXmlField := TXmlNode():new( HBXML_TYPE_CDATA  , ;
                                            Lower( aField[1] ), ;
                                            NIL               , ;
                                            cData               )
            ELSE
               // other fields are written as normal tags
               cData     := FieldGet( Hb_EnumIndex() )
               cData     := Alltrim( CStr( cData ) )
               oXmlField := TXmlNode():new( HBXML_TYPE_TAG    , ;
                                            Lower( aField[1] ), ;
                                            NIL               , ;
                                            cData               )
            ENDIF
            // add field node to record
            oXmlRecord:addBelow( oXmlField )
         NEXT

         // add record node to records
         oXmlNode:addBelow( oXmlRecord )
         SKIP
      ENDDO

      // create XML file
      nFileHandle := FCreate( "Customer.xml" )

      // write the XML tree
      oXmlDoc:write( nFileHandle, HBXML_STYLE_INDENT )

      // close files
      FClose( nFileHandle )
      USE
   RETURN

 

Reading an XML file

// This example uses the Customer.xml file created in the
// prevous example and extracts from it the structure definition
// for the Customer.dbf file.

   PROCEDURE Main
      LOCAL oXmlDoc := TXmlDocument():new()
      LOCAL oXmlNode, aStruct := {}

      oXMlDoc:read( Memoread( "customer.xml" ) )

      oXmlNode := oXmlDoc:findFirst()
      ? oXmlNode:cName

      oXmlNode := oXmlDoc:findFirst( "structure" )
      ? oXmlNode:cName

      oXmlNode := oXmlDoc:findFirst( "field" )

      DO WHILE oXmlNode <> NIL
         // attributes are stored in a hash
         AAdd( aStruct, { oXmlNode:aAttributes[ "name" ]      , ;
                          oXmlNode:aAttributes[ "type" ]      , ;
                          Val( oXmlNode:aAttributes[ "len" ] ), ;
                          Val( oXmlNode:aAttributes[ "dec" ] )  } )

         oXmlNode := oXmlDoc:findNext()
      ENDDO

      AEval( aStruct, {|a| Qout( ValToPrg(a) ) } )
   RETURN

 

Escape characters in XML

// The example demonstrates the effect of HBXML_STYLE_NOESCAPE
// when XML code is created.

   #include "hbXml.ch"

   PROCEDURE Main
      LOCAL oXmlDoc, oXmlNode

      oXmlDoc := TXmlDocument():new( '<?xml version="1.0"?>' )
      oXmlNode:= TXmlNode():new( , "text", , [this must be escaped: "'&<>] )

      oXmlDoc:oRoot:addBelow( oXmlNode )

      ? oXmlDoc:toString()

      ** output:
      // <?xml version="1.0"?>
      // <text>this must be escaped: &quot;&apos;&amp;&lt;&gt;</text>

      ? oXmlDoc:toString( HBXML_STYLE_NOESCAPE )

      ** output:
      // <?xml version="1.0"?>
      // <text>this must be escaped: "'&<></text>
   RETURN

Copyright © 2006-2007 xHarbour.com Inc. All rights reserved.
http://www.xHarbour.com
Created by docmaker.exe