[Gambas-user] XML library with xml multilevel tags
Luigi Carlotto
md9327 at ...120...
Sun Dec 28 02:14:04 CET 2008
Il giorno sab, 27/12/2008 alle 20.04 +0100, Luigi Carlotto ha scritto:
> I do not comprise the reason, but mine precedence post has been
> included like answer in an other mail.
>
> … however…
>
>
> Gambas 2.9.0
>
> Using the gb.xml library, me they are shrewed that the reading can be
> carried out single on files xml to 2 levels.
> I explain myself in better way…
> I have necessity to read xml files, that it contains a composed
> structure from elements, structured in hierarchical way on more
> levels, as an example:
>
> <?xml version="1.0" encoding="UTF8"?>
> <pgDesigner Version="2.0.0">
> <PROJECT Name="bible" PageFormat="A4" PageOrientation="0"
> Revision="14/03/2008 14:44:03" Description="bible" Driver="8.2"
> Author="mgm" Display="0">
> <TABLE Name="tb_log" X="10" Y="6" ColorBack="230,230,230"
> ColorText="0,0,0" ColorBackTitle="230,230,230"
> ColorBackTitleSelected="76,89,166" ColorForeTitle="0,0,0"
> ColorForeTitleSelected="255,255,255" Comment="006C006F0067"
> Option="false" PrimaryKey="tb_log_pk">
> <TABLEFIELD Name="id" Table="tb_log"
> Comment="006900640065006E00740069006600690061006E0074" Length="0"
> NullCheck="true" PrimaryKey="true" Type1="serial"/>
> <INDEX Name="tb_type_personne_idx1" Table="tb_type_personne"
> Unique="true"/>
> </TABLE>
> questa è una prova
> </PROJECT>
> </pgDesigner>
>
> In the example, the hierarchy of the rows xml is composed gives:
> 1) a main element (root) “<pgDesigner>”;
> 2) inside of the root, the element is present “<PROJECT>”;
> 3) under “<PROJECT>” the element is present “<TABLE>”;
> 4) in its turn, the element “<TABLE>” contains a series of other
> heterogenous elements.
>
> Through the gb.xml library, the reading of the file does not notice of
> the closing of tag (Node.Type=XmlReaderNodeType.EndElement), if these
> are sluices on the same definition of the tag, like as an example:
>
> <INDEX Name="tb_type_personne_idx1" Table="tb_type_personne"
> Unique="true"/>
>
> the reading evidences the opening of tag, but the not its closing, for
> which it renders impossible to ago understand if tag following the
> part of a advanced element, or is to the same level of the element
> precedence.
>
> The behavior is various in phase of writing where, through the methods
> “StartElement” and “EndElement”, it is possible to define complex
> structures.
>
> This logic, currently, only forces the use of structures xml on two
> levels.
The spaces contained in the strings do not have particolary functions,
but they make part of the name of the object, and it is not possible to
eliminate them.
In other cases, use the comma in order to separate a list of elements
(es. an Array, Join function), than in reading comes reconverted in
Array (Split function).
With regard to the levels, I have resolved, constructing a series of
classes, based on the objects XmlReader and XmlWriter.
Logic of these objects allows to only read to rows xml multilevel, but
if the tag they are not sluices on if same. In contrary case, the gb.xml
library does not notice of the closing of the tag, for which the
hierarchy it does not come constructed in correct way.
These classes directly work in memory, loading the xml files in a
structure, that it can be read inside of a program.
The writing comes carried out through the same structure of memory.
This logic me slightly seems or faster, and fastly releases the
connections to the file.
Only problem, perhaps, could be the management of large files; I have
tried with xml of 2Mbyte, and I am fast.
Perhaps he can be useful in Gambas…
The structure follows logic, also applied in other languages, than part
from an object Document (pgXmlDocument), that a Root element contains;
like then for all the other elements (pgXmlElement), it contains an
Array of elements and an Array of attributes (pgXmlAttribute).
The connection with the object father, comes managed from the property
Parent (Root does not have Parent, obviously).
It makes me to know if it can interest.
-------------- next part --------------
' Gambas class file
' Module : pgXml.class
' Author : Luigi Carlotto
' Mail : luigi.carlotto at ...120...
' Description: Xml object management.
INHERITS pgObject
CREATE PRIVATE
-------------- next part --------------
' Gambas class file
' Module : pgXmlAttribute.class
' Author : Luigi Carlotto
' Mail : luigi.carlotto at ...120...
' Description: Xml Attribute object management.
INHERITS pgXml
PROPERTY READ Parent AS pgXmlElement
PROPERTY Name AS String
PROPERTY Value AS String
PRIVATE $parent AS pgXmlElement
PRIVATE $name AS String 'name of attribute
PRIVATE $value AS String 'value of attribute
PUBLIC SUB _new(parent AS pgXmlElement, name AS String, OPTIONAL value AS String = "")
$parent = parent
$name = name
$value = value
END
PRIVATE FUNCTION Parent_Read() AS pgXmlElement
RETURN $parent
END
PRIVATE FUNCTION Name_Read() AS String
RETURN $name
END
PRIVATE SUB Name_Write(Value AS String)
$name = Value
END
PRIVATE FUNCTION Value_Read() AS String
RETURN $value
END
PRIVATE SUB Value_Write(Value AS String)
$value = Value
END
-------------- next part --------------
' Gambas class file
' Module : pgXmlDocument.class
' Author : Luigi Carlotto
' Mail : luigi.carlotto at ...120...
' Description: Xml Document object management.
INHERITS pgXml
' Properties
PROPERTY READ Root AS pgXmlElement
PRIVATE $root AS pgXmlElement 'root
'---
' Constructor
'
PUBLIC SUB _new()
$root = NEW pgXmlElement(NULL, "root")
END
PRIVATE FUNCTION Root_Read() AS pgXmlElement
RETURN $root
END
'---
' Load data
'
' @parameter : String : Path
'
PUBLIC SUB Load(path AS String)
DIM oRoot AS pgXmlElement
DIM oElement AS pgXmlElement
DIM oAttribute AS pgXmlAttribute
DIM oXml AS NEW XmlReader
$root.Name = "root"
$root.Elements.Clear()
$root.Attributes.Clear()
oRoot = $root
oXml.Open(path)
DO UNTIL (oXml.Eof)
SELECT CASE oXml.Node.Type
CASE XmlReaderNodeType.Element
oElement = NEW pgXmlElement(oRoot, oXml.Node.Name, oXml.Node.Value)
FOR EACH oXml.Node.Attributes
oAttribute = NEW pgXmlAttribute(oElement, oXml.Node.Name, oXml.Node.Value)
oElement.Attributes.Add(oAttribute)
NEXT
oRoot.Elements.Add(oElement)
oRoot = oElement
CASE XmlReaderNodeType.EndElement
oRoot = oRoot.Parent
CASE XmlReaderNodeType.Text
oElement.Value &= pgString.Trim(oXml.Node.Value)
END SELECT
oXml.Read()
LOOP
oXml.Close()
END
PRIVATE SUB _loadElement(oXml AS XmlWriter, oRoot AS pgXmlElement)
END
'---
' Save data
'
' @parameter : String : Path
' @parameter : String : Indent
' @parameter : String : Encoding
'
PUBLIC SUB Save(path AS String, OPTIONAL indent AS Boolean = TRUE, OPTIONAL encoding AS String = "UTF8")
DIM oXml AS NEW XmlWriter
DIM oXmlElement AS pgXmlElement
oXml.Open(path, indent, encoding)
FOR EACH oXmlElement IN $root.Elements
_saveElement(oXml, oXmlElement)
NEXT
oXml.EndDocument()
END
PRIVATE SUB _saveElement(oXml AS XmlWriter, oRoot AS pgXmlElement)
DIM oXmlElement AS pgXmlElement
DIM oXmlAttribute AS pgXmlAttribute
oXml.StartElement(oRoot.Name)
IF (oRoot.Attributes.Count > 0) THEN
FOR EACH oXmlAttribute IN oRoot.Attributes
oXml.Attribute(oXmlAttribute.Name, oXmlAttribute.Value)
NEXT
END IF
IF (oRoot.Elements.Count > 0) THEN
FOR EACH oXmlElement IN oRoot.Elements
_saveElement(oXml, oXmlElement)
NEXT
END IF
oXml.Text(oRoot.Value)
oXml.EndElement()
END
'---
' Print structure
'
' @parameter : String : Filename
'
PUBLIC SUB Print(filename AS String)
DIM hFile AS File
DIM oXmlElement AS pgXmlElement
IF ($root.Elements.Count > 0) THEN
hFile = OPEN filename FOR OUTPUT CREATE
FOR EACH oXmlElement IN $root.Elements
_printElement(hFile, oXmlElement)
NEXT
CLOSE #hFile
END IF
END
PRIVATE SUB _printElement(hFile AS file, oRoot AS pgXmlElement, OPTIONAL level AS Integer = 0)
DIM oElement AS pgXmlElement
DIM oAttribute AS pgXmlAttribute
IF (NOT pgTest.IsNull(oRoot)) THEN
PRINT #hFile, String(level, " ") & "Start Element: " & oRoot.Name
PRINT #hFile, String(level, " ") & " Value: \"" & oRoot.Value & "\""
IF (oRoot.Attributes.Count > 0) THEN
FOR EACH oAttribute IN oRoot.Attributes
PRINT #hFile, String(level, " ") & " Attribute:" & oAttribute.Name & " = \"" & oAttribute.Value & "\""
NEXT
END IF
IF (oRoot.Elements.Count > 0) THEN
FOR EACH oElement IN oRoot.Elements
_printElement(hFile, oElement, level + 1)
NEXT
END IF
PRINT #hFile, String(level, " ") & "End Element: " & oRoot.Name
END IF
END
-------------- next part --------------
' Gambas class file
' Module : pgXmlElement.class
' Author : Luigi Carlotto
' Mail : luigi.carlotto at ...120...
' Description: Xml Element object management.
INHERITS pgXml
PROPERTY READ Parent AS pgXmlElement
PROPERTY Name AS String
PROPERTY Value AS String
PROPERTY READ Attributes AS Object[]
PROPERTY READ Elements AS Object[]
PROPERTY Tag AS Boolean
PRIVATE $parent AS pgXmlElement
PRIVATE $name AS String 'name of element
PRIVATE $value AS String 'value of element
PRIVATE $attributes AS Object[] 'array of attributes
PRIVATE $elements AS Object[] 'array of elements
PRIVATE $tag AS Boolean
PUBLIC SUB _new(parent AS pgXmlElement, name AS String, OPTIONAL value AS String = "")
$parent = parent
$name = name
$value = value
$attributes = pgBase.NewObjectArray()
$elements = pgBase.NewObjectArray()
END
PRIVATE FUNCTION Parent_Read() AS pgXmlElement
RETURN $parent
END
PRIVATE FUNCTION Name_Read() AS String
RETURN $name
END
PRIVATE SUB Name_Write(Value AS String)
$name = Value
END
PRIVATE FUNCTION Value_Read() AS String
RETURN $value
END
PRIVATE SUB Value_Write(Value AS String)
$value = Value
END
PRIVATE FUNCTION Attributes_Read() AS Object[]
RETURN $attributes
END
PRIVATE FUNCTION Elements_Read() AS Object[]
RETURN $elements
END
PRIVATE FUNCTION Tag_Read() AS Boolean
RETURN $tag
END
PRIVATE SUB Tag_Write(Value AS Boolean)
$tag = Value
END
PUBLIC FUNCTION AddAttribute(name AS String, OPTIONAL value AS String = "") AS pgXmlAttribute
DIM oXmlAttribute AS pgXmlAttribute
oXmlAttribute = NEW pgXmlAttribute(ME, name, value)
$attributes.Add(oXmlAttribute)
RETURN oXmlAttribute
END
PUBLIC FUNCTION AddElement(name AS String, OPTIONAL value AS String = "") AS pgXmlElement
DIM oXmlElement AS pgXmlElement
oXmlElement = NEW pgXmlElement(ME, name, value)
$elements.Add(oXmlElement)
RETURN oXmlElement
END
More information about the User
mailing list