[Gambas-user] Problem with Conv() and XmlWrite

Luigi Carlotto md9327 at ...120...
Sun Dec 28 01:56:33 CET 2008


Il giorno dom, 28/12/2008 alle 01.20 +0100, Luigi Carlotto ha scritto:

> Il giorno sab, 27/12/2008 alle 19.58 +0100, Luigi Carlotto ha scritto:
> 
> > The strings do not contain characters of “Carriage Return” or “Line
> > Feed”, but only space; if you have noticed interruptions, it is only
> > a problem with the mail, or the editor using the function cut&paste.
> > Probably, the option of “wrapping” of the editor, divides the line
> > through spaces, but in the code all in a same and only string are
> > comprised.
> > 
> > The sql commandos are, sometimes, composed from more of a word key,
> > and they do not have sense if dealt in separate way; an example
> > could be the definition of a PostgreSQL field of type “timestamp
> > with time zones”. For program requirements, I have had to list in
> > exact way, all the words key of the language sql, used from the
> > motor of the database.
> > 
> > I have already executed the test on the single characters of the
> > string, and I have not evidenced anomalous situations.
> > As I have already written, the problem verification in phase of
> > passage of the string to function XML; the conversion executed from
> > Conv() is very well.
> > If I execute “PRINT Conv(sType, “UTF-8”, “ASCII”)” from Console, the
> > string it comes visualized in corrected way, with any LANG.
> > 
> > You perfectly have reason on the anomalous use of the attributes,
> > but I have had to use this logic because of an other problem, that I
> > have uncovered using the gb.xml library; it seems that it is not way
> > to read xml files, composed from tag multilevel.
> > With my tests, I have verified that the use of a hierarchical
> > structure, with advanced levels to 2, does not come read, that is,
> > they come only read the tag of first and second level; if a third
> > level is present, comes ignored, etc. 
> > 
> > Like in other languages, the document xml begins with tag
> > “root” (level 1), to which they are connected of the elements (level
> > 2); Every element has, in its turn (attributes to part), a series
> > under elements (level 3), and thus via, in hierarchical way.
> > The methods of the library do not allow to read these ulterior
> > elements, for which they have been forced to use a structure with 2
> > single levels, and the attributes for the values of the single
> > element.
> > 
> > But to part this, probably, and as I had supposed, exists some
> > problem in the writing of attributes much large; but the single
> > anomaly verification with the use of an Asian language, while with
> > the European languages all it works well.
> > 
> > It pardons me for my English bad one.
> > 
> > 
> 
> 
> I have modified the procedures of reading/writing of XML files,
> following your relative suggestion I use to it of the elements
> (eliminating the attributes).
> In spite of this modification, the problem still remains…
> I send new file, in attached, so that it can be read with browser or a
> editor of text, to eliminate problems of reading of invisible
> characters.
> The error code is always the same one:
> 
> encoding error : output conversion failed due to conv error, bytes
> 0xE5 0x31 0x32 0xE5
> I/O error : encoder error
> Error: Error writing XML data
> Code: -1
> 
> I have divided the code, so as to verify if the problem is caused from
> the conversion (Conv), or from the writing xml; you I can confirm that
> the error verification in correspondence of the writing xml, while the
> conversion comes made correctly.
> 
> With the exception of the byte 0x31 (character “1”) and 0x32
> (character “2”), character 0xE5 (224 binary) does not come understood;
> in effects, using PRINT Chr (224) in Gambas Console, they come printed
> two rectangles white. This character, but, is not present in the
> string where the program jams; the string is: ”--,/*, *“ (excluded
> apexes). The same string comes many times over saved, in the same
> function, but the program jams alone on the last one.
> 
> 


In attached shipment 3 classes, that I have constructed on the base of
the objects of the gb.xml library (XmlReader and XmlWriter).
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

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