154 <body> |
154 <body> |
155 <%(body_type)s>%%s</%(body_type)s> |
155 <%(body_type)s>%%s</%(body_type)s> |
156 </body> |
156 </body> |
157 </pou>""" % locals() |
157 </pou>""" % locals() |
158 |
158 |
159 def LoadProject(filepath): |
159 def LoadProjectXML(project_xml): |
160 project_file = open(filepath) |
160 project_xml = project_xml.replace( |
161 project_xml = project_file.read().replace( |
|
162 "http://www.plcopen.org/xml/tc6.xsd", |
161 "http://www.plcopen.org/xml/tc6.xsd", |
163 "http://www.plcopen.org/xml/tc6_0201") |
162 "http://www.plcopen.org/xml/tc6_0201") |
164 for cre, repl in [ |
163 for cre, repl in [ |
165 (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), |
164 (re.compile("(?<!<xhtml:p>)(?:<!\[CDATA\[)"), "<xhtml:p><![CDATA["), |
166 (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: |
165 (re.compile("(?:]]>)(?!</xhtml:p>)"), "]]></xhtml:p>")]: |
167 project_xml = cre.sub(repl, project_xml) |
166 project_xml = cre.sub(repl, project_xml) |
|
167 |
|
168 try: |
|
169 tree, error = PLCOpenParser.LoadXMLString(project_xml) |
|
170 if error is not None: |
|
171 # TODO Validate file according to PLCOpen v1 and modify it for |
|
172 # compatibility with PLCOpen v2 |
|
173 return tree, error |
|
174 return tree, None |
|
175 except Exception, e: |
|
176 return None, e.message |
|
177 |
|
178 def LoadProject(filepath): |
|
179 project_file = open(filepath) |
|
180 project_xml = project_file.read() |
168 project_file.close() |
181 project_file.close() |
169 |
182 return LoadProjectXML(project_xml) |
170 return etree.fromstring(project_xml, PLCOpenParser) |
|
171 |
183 |
172 project_pou_xpath = PLCOpen_XPath("/ppx:project/ppx:types/ppx:pous/ppx:pou") |
184 project_pou_xpath = PLCOpen_XPath("/ppx:project/ppx:types/ppx:pous/ppx:pou") |
173 def LoadPou(xml_string): |
185 def LoadPou(xml_string): |
174 root = etree.fromstring( |
186 root, error = LoadProjectXML(LOAD_POU_PROJECT_TEMPLATE % xml_string) |
175 LOAD_POU_PROJECT_TEMPLATE % xml_string, |
187 return project_pou_xpath(root)[0], error |
176 PLCOpenParser) |
|
177 return project_pou_xpath(root)[0] |
|
178 |
188 |
179 project_pou_instances_xpath = { |
189 project_pou_instances_xpath = { |
180 body_type: PLCOpen_XPath( |
190 body_type: PLCOpen_XPath( |
181 "/ppx:project/ppx:types/ppx:pous/ppx:pou[@name='paste_pou']/ppx:body/ppx:%s/*" % body_type) |
191 "/ppx:project/ppx:types/ppx:pous/ppx:pou[@name='paste_pou']/ppx:body/ppx:%s/*" % body_type) |
182 for body_type in ["FBD", "LD", "SFC"]} |
192 for body_type in ["FBD", "LD", "SFC"]} |
183 def LoadPouInstances(xml_string, body_type): |
193 def LoadPouInstances(xml_string, body_type): |
184 root = etree.fromstring( |
194 root, error = LoadProjectXML( |
185 LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type) % xml_string, |
195 LOAD_POU_INSTANCES_PROJECT_TEMPLATE(body_type) % xml_string) |
186 PLCOpenParser) |
196 return project_pou_instances_xpath[body_type](root), error |
187 return project_pou_instances_xpath[body_type](root) |
|
188 |
197 |
189 def SaveProject(project, filepath): |
198 def SaveProject(project, filepath): |
190 project_file = open(filepath, 'w') |
199 project_file = open(filepath, 'w') |
191 project_file.write(etree.tostring( |
200 project_file.write(etree.tostring( |
192 project, |
201 project, |