# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE', which is part of this source code package.
#
"""XML DSL implementation"""
import os
from typing import Optional
import xml.etree.ElementTree as ET
import xml.etree.ElementInclude as EI
from OpenPisco.CLApp.InputReaderBase import InputReaderBase
from Muscat.Helpers.IO.PathController import PathController
[docs]class XmlToDic(InputReaderBase):
def __init__(self):
super().__init__()
self.ext = ".xml"
[docs] def ReadFromString(self,data:str):
# parser to include automaticaly the xinclude namespace if not present
class parser(ET.XMLParser):
def __init__(self):
super().__init__()
def feed(self,data):
if data.find("xmlns:xi") == -1:
data = data.replace('<data ', '<data xmlns:xi="http://www.w3.org/2001/XInclude" ')
if data.find("&") != -1:
data = data.replace('&', '&')
data = data.replace('&', '&')
super(parser,self).feed(data)
root = ET.fromstring(data, parser=parser())
# resolution of the xinclude using the correct filename path
def loader(href:str, parse):
href = os.path.join(self.filenamePath,href)
href = PathController.GetFullFilenameCurrentDirectory(href)
return EI.default_loader(href, parse)
EI.include(root,loader)
return self.XmlToDic(root)
[docs] def XmlToDic(self,ops):
res = {}
for k,v in ops.attrib.items():
res[k] = v
if ops.text is not None and len(ops.text.strip()):
res["CDATA"] = ops.text
children = []
for child in ops:
children.append(self.XmlToDic(child) )
if len(children):
res["children"] = children
return (ops.tag, res)
[docs]def ConvertToXml(dic,name:Optional[str]=None,indent:int=0):
if name is None:
res = "<data"
else:
res = " "*indent*2+ "<" + str(name)
cdatapresent =False
lres = ""
for item,data in dic.items():
if item == "CDATA":
cdatapresent = True
continue
if item not in ["children", "CDATA"]:
lres += " " + str(item ) + '="' + str(data) + '"'
if len(lres) > 80:
res += lres + "\n"
lres = " "*indent*2
res += lres
if "children" not in dic and "CDATA" not in dic:
res += ' />\n'
return res
res += '>'
if not cdatapresent:
res += '\n'
for item,data in dic.items():
if item == "children" :
for subname,subdata in data:
res += ConvertToXml(subdata,subname,indent+1)
elif item == "CDATA" :
res += "<![CDATA["
res += data
res += "]]>"
if name is not None:
if cdatapresent:
res += "</"+name+">\n"
else:
res += " "*indent*2+"</"+name+">\n"
else:
res += "</data>\n"
if indent == 1 :
res += "\n"
return res
[docs]def CheckIntegrity(GUI=False):
from OpenPisco.TestData import GetTestDataPath
import os
filename = GetTestDataPath() + os.sep + "TestInput.xml"
data = open(filename).read()
ConvertFromXmlToPiscoFormat(data)
reader = XmlToDic()
_, data = reader.ReadFromFile(filename)
string = ConvertToXml(data)
_, data2 = reader.ReadFromString(string)
if str(data) != str(data2):
print(data)
print(data2)
print("error in the conversion")
return "not ok "
str_to_run = '<Action type="Repeate" times="1"> <Action type="ResetTopoOp" TopoOp="IDD" /><Action type="RunTopoOp" TopoOp="IDD" /></Action >'
data = reader.ReadFromString(str_to_run )
print(data)
print(str(data))
return "ok"
if __name__ == '__main__':
print(CheckIntegrity(GUI=True))