Best way to use wx.xml to create an xml file

Hi.

I am an avid C++/wxWidgets user and I’ve decides to make some tests with Python and wxPython.

But when I want to do something, my reference is my previous C++ code so there is often problems.

The one of the moment if, as sais in the title, the creation of xml file (I’m generally using this to store settings, or other datas).

The sample given on the doc page works fine for xml file reading and parsing.

But there is no example for xml file creation.

And if I refer to some C++ code, it doesn’t work due to nodes deletion.

Here is a small piece of code :

def SaveSettings(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, “Settings-file”)
rootNode.AddAttribute(“Version”, “1.0”)

    # Creating a simple xml element node
    node = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, "FirstNode")
    node.AddAttribute("Value", "AttributeValue")
    rootNode.AddChild(node)

    # Adding a classic "text" node
    node.SetNext(wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, "SecondNode"))
    node=node.GetNext()
    node.AddChild(wx.xml.XmlNode(wx.xml.XML_TEXT_NODE, "", "NodeValue"))
    # Creating the xml document
    doc = wx.xml.XmlDocument()
    doc.SetRoot(rootNode)
    # Saving the xml file to disc
    doc.Save(filename)

``

Running this on Windows (Python 3.5.1 / wxPython-Phoenix 3.0.3.dev2043) produce a crash.

This is surely due to the deletion of the “node” and “rootNode” vars but I really don’t know how to achieve this with wx.xml classes.

Any advice would be appreciated.

Regards

Xav’

There are many areas where wxWidgets includes functionality that is
already built-in to Python. As a general rule, it’s generally
better to use the built-in Python interfaces when there are
duplications. Python includes several very good XML libraries
already.
However, if you are accustomed to using the wx.xml code from your
C++ work, I can understand not wanting to reinvent your knowledge.
The problem you have here is somewhat complicated. The “SetNext”
API is a very low-level API, designed to be called from inside the
library. In this particular case, “SetNext” does not change the
parentage of the nodes. So, when you do this:
node.SetNext(wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE,
“SecondNode”))
you are creating a node without a parent. Now, you could argue that
SetNext ought to object if the new node does not have the same
parent as the old node, but it doesn’t. You can make it do so by
specifying the parent in the constructor:
node.SetNext(wx.xml.XmlNode(rootNode,
wx.xml.XML_ELEMENT_NODE, “SecondNode”))
but even that has problems. When you create that second node and
provide a parent, it gets inserted at the front of the sibling
list. So, SecondNode points to FirstNode, which points to null.
When you call node.SetNext, that tells FirstNode to point back to
SecondNode, and that creates an infinite loop.
You shouldn’t really worry about the ordering of the entries. It
doesn’t change the meaning of the XML file, and the GetNext/SetNext
APIs don’t work the way you think anyway. Here’s my replacement for
your code:
rootNode = wx.xml.XmlNode(None, wx.xml.XML_ELEMENT_NODE,
“Settings-file”)
rootNode.AddAttribute(“Version”, “1.0”)
# Creating a simple xml element node
node = wx.xml.XmlNode(rootNode,wx.xml.XML_ELEMENT_NODE,
“FirstNode”)
node.AddAttribute(“Value”, “AttributeValue”)
# Adding a classic “text” node
node = wx.xml.XmlNode(rootNode, wx.xml.XML_ELEMENT_NODE,
“SecondNode”)
wx.xml.XmlNode(node, wx.xml.XML_TEXT_NODE, “”, “NodeValue”)
Now each node specifies its parentage at construction time.

···

Xaviou wrote:

      I am an avid C++/wxWidgets user and I've decides to make

some tests with Python and wxPython.

      But when I want to do something, my reference is my

previous C++ code so there is often problems.

      The one of the moment if, as sais in the title, the

creation of xml file (I’m generally using this to store
settings, or other datas).

-- Tim Roberts, Providenza & Boekelheide, Inc.

timr@probo.com

You'll be happier in the long run if you use Python to do your XML
manipulation.

But even happier if you DON'T use XML for settings, etc.... Use JSON, or
YAML, or pretty much anything else :slight_smile:

-CHB

···

On Tue, May 24, 2016 at 11:44 AM, Tim Roberts <timr@probo.com> wrote:

Xaviou wrote:

The one of the moment if, as sais in the title, the creation of xml file
(I'm generally using this to store settings, or other datas).

There are many areas where wxWidgets includes functionality that is
already built-in to Python. As a general rule, it's generally better to
use the built-in Python interfaces when there are duplications. Python
includes several very good XML libraries already.

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Of course if you would like to simplify both your wxPython code and your
C++ wxWidgets code then you could use the wx.FileConfig/wxFileConfig
class, (or if you don't mind having your configuration in the registry
on Windows you can use wxConfig), - while it uses INI file format that
is usually sufficient for most settings.

···

On 24/05/2016 20:00, Chris Barker wrote:

On Tue, May 24, 2016 at 11:44 AM, Tim Roberts <timr@probo.com > <mailto:timr@probo.com>> wrote:

    Xaviou wrote:

    The one of the moment if, as sais in the title, the creation of
    xml file (I'm generally using this to store settings, or other datas).

    There are many areas where wxWidgets includes functionality that is
    already built-in to Python. As a general rule, it's generally
    better to use the built-in Python interfaces when there are
    duplications. Python includes several very good XML libraries already.

You'll be happier in the long run if you use Python to do your XML
manipulation.

But even happier if you DON'T use XML for settings, etc.... Use JSON, or
YAML, or pretty much anything else :slight_smile:

-CHB

--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.

Hi

Tim Roberts wrote :

There are many areas where wxWidgets includes functionality that is already built-in to Python.  As a general rule, it's generally better to use the built-in Python interfaces when there are duplications.  Python includes several very good XML libraries already.

This is the way I’ve searched when I saw that my wxWidgets based code wasn’t working.
And using “xml.etree.ElementTree” is a quite simple thing.
But I started this thread to understand why it wasn’t working.

But I agree with you and Chris Barker : It is better to directly use Python for something when it is availabale.

To simplify my question : is there a way to make the following code not crashing Python ?

def CreateXmlFile(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, “TestXmlFile”)
doc = wx.xml.XmlDocument()
doc.SetRoot(rootNode)

    return doc.Save(filename)

``

Note that the xml file is correctly created.
(I think) the crash arrives when the datas are destructed from memory (content of rootNode destructed twice ?)

The only way I’ve found is detaching the root node from the xml document before exiting from the function :
def CreateXmlFile(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, “TestXmlFile”)
doc = wx.xml.XmlDocument()
doc.SetRoot(rootNode)

    res = doc.Save(filename)
    doc.DetachRoot()

    return res

``

but I’m not sure that it is correct and enough.

Regards

Xav’

Yes, this looks like a bug in Phoenix. I'm working on submitting a fix.

Scott

···

On Wed, 25 May 2016, Xaviou wrote:

To simplify my question : is there a way to make the following code not
crashing Python ?

def CreateXmlFile(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, "TestXmlFile")
doc = wx.xml.XmlDocument()
doc.SetRoot(rootNode)

    return doc\.Save\(filename\)

Note that the xml file is correctly created.(I think) the crash arrives
when the datas are destructed from memory (content of rootNode destructed
twice ?)

The only way I've found is detaching the root node from the xml document
before exiting from the function :def CreateXmlFile(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, "TestXmlFile")
doc = wx.xml.XmlDocument()
doc.SetRoot(rootNode)

    res = doc\.Save\(filename\)
    doc\.DetachRoot\(\)

    return res

but I'm not sure that it is correct and enough.

PR submitted:

Scott

···

On Fri, 27 May 2016, Scott Talbert wrote:

To simplify my question : is there a way to make the following code not
crashing Python ?

def CreateXmlFile(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, "TestXmlFile")
doc = wx.xml.XmlDocument()
doc.SetRoot(rootNode)

    return doc\.Save\(filename\)

Note that the xml file is correctly created.(I think) the crash arrives
when the datas are destructed from memory (content of rootNode destructed
twice ?)

The only way I've found is detaching the root node from the xml document
before exiting from the function :def CreateXmlFile(filename):
rootNode = wx.xml.XmlNode(wx.xml.XML_ELEMENT_NODE, "TestXmlFile")
doc = wx.xml.XmlDocument()
doc.SetRoot(rootNode)

    res = doc\.Save\(filename\)
    doc\.DetachRoot\(\)

    return res

but I'm not sure that it is correct and enough.

Yes, this looks like a bug in Phoenix. I'm working on submitting a fix.