--- a/CodeFileTreeNode.py Tue Sep 10 23:23:45 2013 +0200
+++ b/CodeFileTreeNode.py Wed Sep 11 23:48:41 2013 +0200
@@ -1,13 +1,14 @@
-from xml.dom import minidom
-from xmlclass import GenerateClassesFromXSDstring, UpdateXMLClassGlobals
+from copy import deepcopy +from xmlclass import GenerateParserFromXSDstring from PLCControler import UndoBuffer
CODEFILE_XSD = """<?xml version="1.0" encoding="ISO-8859-1" ?>
-<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xhtml="http://www.w3.org/1999/xhtml"> <xsd:element name="%(codefile_name)s">
@@ -65,22 +66,29 @@
[SECTION_TAG_ELEMENT % name
for name in self.SECTIONS_NAMES if name != "includes"])
- self.CodeFileClasses = GenerateClassesFromXSDstring(
+ self.CodeFileParser = GenerateParserFromXSDstring( CODEFILE_XSD % sections_str)
+ self.CodeFileVariables = etree.XPath("variables/variable") filepath = self.CodeFileName()
- self.CodeFile = self.CodeFileClasses[self.CODEFILE_NAME]()
if os.path.isfile(filepath):
xmlfile = open(filepath, 'r')
- tree = minidom.parse(xmlfile)
+ codefile_xml = xmlfile.read() - for child in tree.childNodes:
- if child.nodeType == tree.ELEMENT_NODE and child.nodeName in [self.CODEFILE_NAME]:
- self.CodeFile.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
- self.CreateCodeFileBuffer(True)
+ codefile_xml = codefile_xml.replace( + '<%s>' % self.CODEFILE_NAME, + '<%s xmlns:xhtml="http://www.w3.org/1999/xhtml">' % self.CODEFILE_NAME) + (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), + (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: + codefile_xml = cre.sub(repl, codefile_xml) + self.CodeFile = etree.fromstring(codefile_xml, self.CodeFileParser) + self.CreateCodeFileBuffer(True) + self.CodeFile = self.CodeFileParser.CreateRoot() self.CreateCodeFileBuffer(False)
@@ -99,7 +107,7 @@
def SetVariables(self, variables):
self.CodeFile.variables.setvariable([])
- variable = self.CodeFileClasses["variables_variable"]()
+ variable = self.CodeFileParser.CreateElement("variable", "variables") variable.setname(var["Name"])
variable.settype(var["Type"])
variable.setinitial(var["Initial"])
@@ -107,7 +115,7 @@
- for var in self.CodeFile.variables.getvariable():
+ for var in self.CodeFileVariables(self.CodeFile): datas.append({"Name" : var.getname(),
"Initial" : var.getinitial()})
@@ -117,10 +125,10 @@
for section in self.SECTIONS_NAMES:
section_code = parts.get(section)
if section_code is not None:
- getattr(self.CodeFile, section).settext(section_code)
+ getattr(self.CodeFile, section).setanyText(section_code) - return dict([(section, getattr(self.CodeFile, section).gettext())
+ return dict([(section, getattr(self.CodeFile, section).getanyText()) for section in self.SECTIONS_NAMES])
def CTNTestModified(self):
@@ -129,11 +137,12 @@
def OnCTNSave(self, from_project_path=None):
filepath = self.CodeFileName()
- text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
- text += self.CodeFile.generateXMLText(self.CODEFILE_NAME, 0)
xmlfile = open(filepath,"w")
- xmlfile.write(text.encode("utf-8"))
+ xmlfile.write(etree.tostring( self.MarkCodeFileAsSaved()
@@ -144,39 +153,31 @@
return [(variable.getname(),
- for variable in self.CodeFile.variables.variable]
+ for variable in self.CodeFileVariables(self.CodeFile)] #-------------------------------------------------------------------------------
# Current Buffering Management Functions
#-------------------------------------------------------------------------------
- def cPickle_loads(self, str_obj):
- UpdateXMLClassGlobals(self.CodeFileClasses)
- return cPickle.loads(str_obj)
- def cPickle_dumps(self, obj):
- UpdateXMLClassGlobals(self.CodeFileClasses)
- return cPickle.dumps(obj)
Return a copy of the codefile model
- return self.cPickle_loads(self.cPickle_dumps(model))
def CreateCodeFileBuffer(self, saved):
- self.CodeFileBuffer = UndoBuffer(self.cPickle_dumps(self.CodeFile), saved)
+ self.CodeFileBuffer = UndoBuffer(self.CodeFileParser.Dumps(self.CodeFile), saved) def BufferCodeFile(self):
- self.CodeFileBuffer.Buffering(self.cPickle_dumps(self.CodeFile))
+ self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile)) def StartBuffering(self):
- self.CodeFileBuffer.Buffering(self.cPickle_dumps(self.CodeFile))
+ self.CodeFileBuffer.Buffering(self.CodeFileParser.Dumps(self.CodeFile)) def MarkCodeFileAsSaved(self):
@@ -188,10 +189,10 @@
- self.CodeFile = self.cPickle_loads(self.CodeFileBuffer.Previous())
+ self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Previous()) - self.CodeFile = self.cPickle_loads(self.CodeFileBuffer.Next())
+ self.CodeFile = self.CodeFileParser.Loads(self.CodeFileBuffer.Next()) def GetBufferState(self):
first = self.CodeFileBuffer.IsFirst() and not self.Buffering
--- a/ConfigTreeNode.py Tue Sep 10 23:23:45 2013 +0200
+++ b/ConfigTreeNode.py Wed Sep 11 23:48:41 2013 +0200
@@ -9,15 +9,15 @@
import os,traceback,types
-from xml.dom import minidom
-from xmlclass import GenerateClassesFromXSDstring
+from xmlclass import GenerateParserFromXSDstring from util.misc import GetClassImporter
from PLCControler import PLCControler, LOCATION_CONFNODE
from editors.ConfTreeNodeEditor import ConfTreeNodeEditor
-_BaseParamsClass = GenerateClassesFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?>
+_BaseParamsParser = GenerateParserFromXSDstring("""<?xml version="1.0" encoding="ISO-8859-1" ?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="BaseParams">
@@ -26,7 +26,7 @@
<xsd:attribute name="Enabled" type="xsd:boolean" use="optional" default="true"/>
- </xsd:schema>""")["BaseParams"]
@@ -46,17 +46,15 @@
def _AddParamsMembers(self):
- self.Classes = GenerateClassesFromXSDstring(self.XSD)
- Classes = [(name, XSDclass) for name, XSDclass in self.Classes.items() if XSDclass.IsBaseClass]
- name, XSDclass = Classes[0]
- self.CTNParams = (name, obj)
- setattr(self, name, obj)
+ self.Parser = GenerateParserFromXSDstring(self.XSD) + obj = self.Parser.CreateRoot() + name = obj.getLocalTag() + self.CTNParams = (name, obj) + setattr(self, name, obj) - self.BaseParams = _BaseParamsClass()
+ self.BaseParams = _BaseParamsParser.CreateRoot() self.MandatoryParams = ("BaseParams", self.BaseParams)
@@ -170,15 +168,21 @@
# generate XML for base XML parameters controller of the confnode
BaseXMLFile = open(self.ConfNodeBaseXmlFilePath(),'w')
- BaseXMLFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
- BaseXMLFile.write(self.MandatoryParams[1].generateXMLText(self.MandatoryParams[0], 0).encode("utf-8"))
+ BaseXMLFile.write(etree.tostring( + self.MandatoryParams[1], # generate XML for XML parameters controller of the confnode
XMLFile = open(self.ConfNodeXmlFilePath(),'w')
- XMLFile.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
- XMLFile.write(self.CTNParams[1].generateXMLText(self.CTNParams[0], 0).encode("utf-8"))
+ XMLFile.write(etree.tostring( # Call the confnode specific OnCTNSave method
@@ -581,8 +585,9 @@
basexmlfile = open(self.ConfNodeBaseXmlFilePath(CTNName), 'r')
- basetree = minidom.parse(basexmlfile)
- self.MandatoryParams[1].loadXMLTree(basetree.childNodes[0])
+ self.BaseParams = etree.fromstring( + basexmlfile.read(), _BaseParamsParser) + self.MandatoryParams = ("BaseParams", self.BaseParams) self.GetCTRoot().logger.write_error(_("Couldn't load confnode base parameters %s :\n %s") % (CTNName, unicode(exc)))
@@ -592,8 +597,10 @@
xmlfile = open(self.ConfNodeXmlFilePath(CTNName), 'r')
- tree = minidom.parse(xmlfile)
- self.CTNParams[1].loadXMLTree(tree.childNodes[0])
+ obj = etree.fromstring(xmlfile.read(), self.Parser) + name = obj.getLocalTag() + setattr(self, name, obj) + self.CTNParams = (name, obj) self.GetCTRoot().logger.write_error(_("Couldn't load confnode parameters %s :\n %s") % (CTNName, unicode(exc)))
--- a/PLCGenerator.py Tue Sep 10 23:23:45 2013 +0200
+++ b/PLCGenerator.py Wed Sep 11 23:48:41 2013 +0200
@@ -271,10 +271,15 @@
varlists = [(varlist, varlist.getvariable()[:]) for varlist in configuration.getglobalVars()]
extra_variables = self.Controler.GetConfigurationExtraVariables()
- if len(extra_variables) > 0:
- varlists = [(PLCOpenParser.CreateElement("globalVars", "interface"), [])]
- varlists[-1][1].extend(extra_variables)
+ extra_global_vars = None + if len(extra_variables) > 0 and len(varlists) == 0: + extra_global_vars = PLCOpenParser.CreateElement("globalVars", "interface") + configuration.setglobalVars([extra_global_vars]) + varlists = [(extra_global_vars, [])] + for variable in extra_variables: + varlists[-1][0].appendvariable(variable) + varlists[-1][1].append(variable) # Generate any global variable in configuration
for varlist, varlist_variables in varlists:
@@ -310,12 +315,19 @@
(var.gettypeAsText(), (tagname, variable_type, var_number, "type"))]
# Generate variable initial value if exists
initial = var.getinitialValue()
+ if initial is not None: (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))]
config += [(" END_VAR\n", ())]
+ if extra_global_vars is not None: + configuration.remove(extra_global_vars) + for variable in extra_variables: + varlists[-1][1].remove(variable) # Generate any resource in the configuration
for resource in configuration.getresource():
config += self.GenerateResource(resource, configuration.getname())
@@ -363,7 +375,7 @@
(var.gettypeAsText(), (tagname, variable_type, var_number, "type"))]
# Generate variable initial value if exists
initial = var.getinitialValue()
+ if initial is not None: (self.ComputeValue(initial.getvalue(), var_type), (tagname, variable_type, var_number, "initial value"))]
@@ -380,13 +392,13 @@
single = task.getsingle()
# Single argument if exists
resrce += [("SINGLE := ", ()),
(single, (tagname, "task", task_number, "single")),
# Interval argument if exists
interval = task.getinterval()
+ if interval is not None: resrce += [("INTERVAL := ", ()),
(interval, (tagname, "task", task_number, "interval")),
--- a/c_ext/c_ext.py Tue Sep 10 23:23:45 2013 +0200
+++ b/c_ext/c_ext.py Wed Sep 11 23:48:41 2013 +0200
@@ -25,9 +25,6 @@
- def GenerateClassesFromXSDstring(self, xsd_string):
- return GenerateClassesFromXSDstring(xsd_string)
@@ -56,7 +53,7 @@
text += "/* User includes */\n"
- text += self.CodeFile.includes.gettext().strip()
+ text += self.CodeFile.includes.getanyText().strip() text += '#include "iec_types_all.h"\n\n'
@@ -76,25 +73,25 @@
# Adding user global variables and routines
text += "/* User internal user variables and routines */\n"
- text += self.CodeFile.globals.gettext().strip()
+ text += self.CodeFile.globals.getanyText().strip() # Adding Beremiz confnode functions
text += "/* Beremiz confnode functions */\n"
text += "int __init_%s(int argc,char **argv)\n{\n"%location_str
- text += self.CodeFile.initFunction.gettext().strip()
+ text += self.CodeFile.initFunction.getanyText().strip() text += " return 0;\n}\n\n"
text += "void __cleanup_%s(void)\n{\n"%location_str
- text += self.CodeFile.cleanUpFunction.gettext().strip()
+ text += self.CodeFile.cleanUpFunction.getanyText().strip() text += "void __retrieve_%s(void)\n{\n"%location_str
- text += self.CodeFile.retrieveFunction.gettext().strip()
+ text += self.CodeFile.retrieveFunction.getanyText().strip() text += "void __publish_%s(void)\n{\n"%location_str
- text += self.CodeFile.publishFunction.gettext().strip()
+ text += self.CodeFile.publishFunction.getanyText().strip() Gen_Cfile_path = os.path.join(buildpath, "CFile_%s.c"%location_str)
--- a/py_ext/PythonFileCTNMixin.py Tue Sep 10 23:23:45 2013 +0200
+++ b/py_ext/PythonFileCTNMixin.py Wed Sep 11 23:48:41 2013 +0200
@@ -1,14 +1,10 @@
-from PLCControler import UndoBuffer
-from PythonEditor import PythonEditor
-from xml.dom import minidom
-from xmlclass import GenerateClassesFromXSD
+from xmlclass import GenerateParserFromXSD from CodeFileTreeNode import CodeFile
-PythonClasses = GenerateClassesFromXSD(os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd"))
+from PythonEditor import PythonEditor class PythonFileCTNMixin(CodeFile):
@@ -26,19 +22,27 @@
filepath = self.PythonFileName()
- python_code = PythonClasses["Python"]()
if os.path.isfile(filepath):
+ PythonParser = GenerateParserFromXSD( + os.path.join(os.path.dirname(__file__), "py_ext_xsd.xsd")) xmlfile = open(filepath, 'r')
- tree = minidom.parse(xmlfile)
+ pythonfile_xml = xmlfile.read() - for child in tree.childNodes:
- if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "Python":
- python_code.loadXMLTree(child, ["xmlns", "xmlns:xsi", "xsi:schemaLocation"])
- self.CodeFile.globals.settext(python_code.gettext())
- self.CreateCodeFileBuffer(False)
+ pythonfile_xml = pythonfile_xml.replace( + 'xmlns="http://www.w3.org/2001/XMLSchema"', + 'xmlns:xhtml="http://www.w3.org/1999/xhtml"') + (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), + (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: + pythonfile_xml = cre.sub(repl, pythonfile_xml) + python_code = etree.fromstring(pythonfile_xml, PythonParser) + self.CodeFile.globals.setanyText(python_code.getanyText()) + self.CreateCodeFileBuffer(False) return os.path.join(self.CTNPath(), "pyfile.xml")
@@ -50,7 +54,7 @@
def GetSection(self,section):
return self.PreSectionsTexts.get(section,"") + "\n" + \
- getattr(self.CodeFile, section).gettext() + "\n" + \
+ getattr(self.CodeFile, section).getanyText() + "\n" + \ self.PostSectionsTexts.get(section,"")
--- a/xmlclass/xmlclass.py Tue Sep 10 23:23:45 2013 +0200
+++ b/xmlclass/xmlclass.py Wed Sep 11 23:48:41 2013 +0200
@@ -610,7 +610,7 @@
value = infos["elmt_type"]["initial"]()
DefaultElementClass.__setattr__(value, "tag", element_name)
return [initial_value() for i in xrange(infos["minOccurs"])]
@@ -664,7 +664,9 @@
if choices_dict.has_key(choice_name):
raise ValueError("'%s' element defined two times in choice" % choice_name)
choices_dict[choice_name] = infos
- choices_xpath = "|".join(map(lambda x: "%s:%s" % (factory.TargetNamespace, x), choices_dict.keys()))
+ prefix = ("%s:" % factory.TargetNamespace + if factory.TargetNamespace is not None else "") + choices_xpath = "|".join(map(lambda x: prefix + x, choices_dict.keys())) content_name, infos = choices[0]
@@ -1127,7 +1129,7 @@
classmembers["set%s" % elmtname] = generateSetMethod(elmtname)
classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
- classmembers["init"] = generateInitMethod(self, classinfos)
+ classmembers["_init_"] = generateInitMethod(self, classinfos) classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos)
classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos)
classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
@@ -1251,7 +1253,9 @@
element_infos["elmt_type"]["generate"](self, value)
- element_xpath = ("%s:%s" % (factory.TargetNamespace, name)
+ prefix = ("%s:" % factory.TargetNamespace + if factory.TargetNamespace is not None else "") + element_xpath = (prefix + name else elements["content"]["elmt_type"]["choices_xpath"].path)
@@ -1262,7 +1266,7 @@
element_idx = elements.keys().index(name)
previous_elements_xpath = "|".join(map(
- lambda x: "%s:%s" % (factory.TargetNamespace, x)
else elements["content"]["elmt_type"]["choices_xpath"].path,
elements.keys()[:element_idx]))
@@ -1341,7 +1345,7 @@
elements[parts[0]]["elmt_type"]["facets"])
value = getattr(self, parts[0], "")
elif parts[0] == "content":
- return self.content["value"].getElementInfos(self.content["name"], path)
+ return self.content.getElementInfos(self.content.getLocalTag(), path) attr = getattr(self, parts[0], None)
@@ -1352,7 +1356,7 @@
return attr.getElementInfos(parts[0], parts[1])
elif elements.has_key("content"):
- return self.content["value"].getElementInfos(name, path)
+ return self.content.getElementInfos(name, path) elif classinfos.has_key("base"):
classinfos["base"].getElementInfos(name, path)
@@ -1370,15 +1374,9 @@
- value = self.content["name"]
- if self.content["value"] is not None:
- if self.content["name"] == "sequence":
- choices_dict = dict([(choice["name"], choice) for choice in element["choices"]])
- sequence_infos = choices_dict.get("sequence", None)
- if sequence_infos is not None:
- children.extend([item.getElementInfos(infos["name"]) for item, infos in zip(self.content["value"], sequence_infos["elements"])])
- children.extend(self.content["value"].getElementInfos(self.content["name"])["children"])
+ value = self.content.getLocalTag() + if self.content is not None: + children.extend(self.content.getElementInfos(value)["children"]) elif element["elmt_type"]["type"] == SIMPLETYPE:
children.append({"name": element_name, "require": element["minOccurs"] != 0,
"type": gettypeinfos(element["elmt_type"]["basename"],
@@ -1435,13 +1433,13 @@
instance.setElementValue(None, value)
elif elements.has_key("content"):
- self.content["value"].setElementValue(path, value)
+ self.content.setElementValue(path, value) elif classinfos.has_key("base"):
classinfos["base"].setElementValue(self, path, value)
elif elements.has_key("content"):
if elements["content"]["minOccurs"] == 0:
raise ValueError("\"content\" element is required!")
@@ -1454,7 +1452,7 @@
def generateInitMethod(factory, classinfos):
if classinfos.has_key("base"):
- classinfos["base"].init(self)
+ classinfos["base"]._init_(self) for attribute in classinfos["attributes"]:
attribute["attr_type"] = FindTypeInfos(factory, attribute["attr_type"])
if attribute["use"] == "required":
@@ -1491,7 +1489,7 @@
value = infos["elmt_type"]["initial"]()
DefaultElementClass.__setattr__(value, "tag", factory.etreeNamespaceFormat % attr)
setattr(self, attr, value)
raise ValueError("Invalid class attribute!")
@@ -1541,6 +1539,7 @@
raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
new_content = choices[content_type]["elmt_type"]["initial"]()
+ DefaultElementClass.__setattr__(new_content, "tag", factory.etreeNamespaceFormat % content_type) self.content = new_content
@@ -1553,6 +1552,7 @@
choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
new_element = choices[content_type]["elmt_type"]["initial"]()
+ DefaultElementClass.__setattr__(new_element, "tag", factory.etreeNamespaceFormat % content_type) self.appendcontent(new_element)
@@ -1567,6 +1567,7 @@
choices[type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
new_element = choices[content_type]["elmt_type"]["initial"]()
+ DefaultElementClass.__setattr__(new_element, "tag", factory.etreeNamespaceFormat % content_type) self.insertcontent(index, new_element)
@@ -1595,7 +1596,7 @@
class DefaultElementClass(etree.ElementBase):
@@ -1657,7 +1658,7 @@
self.DefaultNamespaceFormat % self.BaseClass[0],
@@ -1671,16 +1672,14 @@
def CreateElement(self, element_tag, parent_tag=None):
new_element = self.GetElementClass(element_tag, parent_tag)()
DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
def GenerateParser(factory, xsdstring):
ComputedClasses = factory.CreateClasses()
if factory.FileName is not None and len(ComputedClasses) == 1:
ComputedClasses = ComputedClasses[factory.FileName]
- BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass]
+ BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass] UpdateXMLClassGlobals(ComputedClasses)
--- a/xmlclass/xsdschema.py Tue Sep 10 23:23:45 2013 +0200
+++ b/xmlclass/xsdschema.py Wed Sep 11 23:48:41 2013 +0200
@@ -939,9 +939,10 @@
factory.BlockDefault = attributes["blockDefault"]
factory.FinalDefault = attributes["finalDefault"]
- factory.TargetNamespace = factory.DefinedNamespaces.get(attributes["targetNamespace"], None)
+ targetNamespace = attributes.get("targetNamespace", None) + factory.TargetNamespace = factory.DefinedNamespaces.get(targetNamespace, None) if factory.TargetNamespace is not None:
- factory.etreeNamespaceFormat = "{%s}%%s" % attributes["targetNamespace"]
+ factory.etreeNamespaceFormat = "{%s}%%s" % targetNamespace factory.Namespaces[factory.TargetNamespace] = {}
annotations, children = factory.ReduceElements(elements, True)
@@ -1097,7 +1098,7 @@
This function generate a xml from the xsd given as a string
def GenerateParserFromXSDstring(xsdstring):
- return GenerateParser(XSDClassFactory(minidom.parseString(xsdstring)))
+ return GenerateParser(XSDClassFactory(minidom.parseString(xsdstring)), xsdstring) #-------------------------------------------------------------------------------
@@ -2521,19 +2522,3 @@
"anyType": {"type": COMPLEXTYPE, "extract": lambda x:None},
-if __name__ == '__main__':
- classes = GenerateClassesFromXSD("test.xsd")
- # Code for test of test.xsd
- xmlfile = open("po.xml", 'r')
- tree = minidom.parse(xmlfile)
- test = classes["PurchaseOrderType"]()
- for child in tree.childNodes:
- if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "purchaseOrder":
- test.loadXMLTree(child)
- test.items.item[0].setquantity(2)
- testfile = open("test.xml", 'w')
- testfile.write(u'<?xml version=\"1.0\"?>\n')
- testfile.write(test.generateXMLText("purchaseOrder").encode("utf-8"))