# 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.
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).
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
-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
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
-CHB
--
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect
those of my employer.
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 ?
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
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
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.