xHarbour Reference Documentation > Class Reference (textmode) |
Creates a new TXmlDocument object.
TXmlDocument():new( [<nFileHandle>|<cXmlString>], [<nStyle>] ) --> oTXmlDocument
Constants for XML object creation
Constant | Value | Description |
---|---|---|
HBXML_STYLE_INDENT | 1 | Indents XML nodes with one space |
HBXML_STYLE_TAB | 2 | Indents XML nodes with tabs |
HBXML_STYLE_THREESPACES | 4 | Indents XML nodes with three spaces |
HBXML_STYLE_NOESCAPE | 8 | Reads 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.
Function TXmlDocument() creates the object and method :new() initializes it.
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.
See also: | TXmlIterator(), TXmlIteratorRegEx(), TXmlIteratorScan(), TXmlNode() |
Category: | Object functions , xHarbour extensions |
Header: | hbxml.ch |
Source: | rtl\txml.prg |
LIB: | xhb.lib |
DLL: | xhbdll.dll |
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: "'&<></text> ? oXmlDoc:toString( HBXML_STYLE_NOESCAPE ) ** output: // <?xml version="1.0"?> // <text>this must be escaped: "'&<></text> RETURN
http://www.xHarbour.com