|
|
|
@ -22,7 +22,8 @@ from copy import deepcopy
|
|
|
|
|
# def appendChild(*args, **kwargs):
|
|
|
|
|
# ET._Element.append(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def display(xml):
|
|
|
|
|
print(str(ET.tostring(xml, pretty_print=True), encoding="UTF-8"))
|
|
|
|
|
# ET._Element.appendChild = appendChild
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -33,14 +34,41 @@ class xpath():
|
|
|
|
|
f = ET.XPath(xpath)
|
|
|
|
|
return f(xml)
|
|
|
|
|
|
|
|
|
|
#can't add methods to Cython lib. Gotta do this
|
|
|
|
|
#can't add methods to Cython lib.
|
|
|
|
|
#have to do this the ugly way
|
|
|
|
|
def firstChild(element):
|
|
|
|
|
# f = ET.XPath("//*[1]")
|
|
|
|
|
# found = f(element)
|
|
|
|
|
# print("DEBUG FIRST CHILD")
|
|
|
|
|
# display(element)
|
|
|
|
|
# display(found[0])
|
|
|
|
|
# print("DEBUG FIRST CHILD")
|
|
|
|
|
# display(element)
|
|
|
|
|
if(element.text):
|
|
|
|
|
# print("element has text")
|
|
|
|
|
# print(element.text)
|
|
|
|
|
return element
|
|
|
|
|
if(len(element) == 0):
|
|
|
|
|
# print("element empty")
|
|
|
|
|
# print(None)
|
|
|
|
|
return None
|
|
|
|
|
# print("element has a child")
|
|
|
|
|
# print(element[0])
|
|
|
|
|
return element[0]
|
|
|
|
|
# def firstChild(element):
|
|
|
|
|
# if(element.text):
|
|
|
|
|
# return element.text
|
|
|
|
|
# if(len(element) == 0):
|
|
|
|
|
# return None
|
|
|
|
|
# return element[0]
|
|
|
|
|
|
|
|
|
|
def insertBefore(elem, new_child, ref_child):
|
|
|
|
|
#don't actually need parent element, its here just so we can have structure similar to old elem.insertBefore(new_child, ref_child)
|
|
|
|
|
|
|
|
|
|
child_parent = new_child.getparent()
|
|
|
|
|
if child_parent is not None:
|
|
|
|
|
child_parent.remove(new_child)
|
|
|
|
|
if(ref_child is None):
|
|
|
|
|
elem.append(new_child)
|
|
|
|
|
ref_child.addprevious(new_child)
|
|
|
|
|
return new_child
|
|
|
|
|
|
|
|
|
@ -53,11 +81,15 @@ class xmlShare(object):
|
|
|
|
|
if not isinstance(attributes, dict):
|
|
|
|
|
attributes = {}
|
|
|
|
|
|
|
|
|
|
element = ET.SubElement(doc, tag, attributes)
|
|
|
|
|
# element = ET.SubElement(doc, tag, attributes)
|
|
|
|
|
element = ET.Element(tag, attributes)
|
|
|
|
|
# print(type(element))
|
|
|
|
|
# print(dir(element))
|
|
|
|
|
# raise Exception
|
|
|
|
|
# element = doc.createElement(tag)
|
|
|
|
|
# print(tag)
|
|
|
|
|
# print(text)
|
|
|
|
|
# print(attributes)
|
|
|
|
|
if text:
|
|
|
|
|
# txtNode = doc.createTextNode(_u(text))
|
|
|
|
|
# txtNode = doc.createTextNode(text)
|
|
|
|
@ -67,7 +99,6 @@ class xmlShare(object):
|
|
|
|
|
# attribute = doc.createAttribute(attr)
|
|
|
|
|
# attribute.text = attributes[attr]
|
|
|
|
|
# element.setAttributeNode(attribute)
|
|
|
|
|
# print("++++++")
|
|
|
|
|
# print(ET.tostring(element, pretty_print=True))
|
|
|
|
|
return element
|
|
|
|
|
|
|
|
|
@ -210,7 +241,7 @@ class xmlDoc(object):
|
|
|
|
|
docTxt = ('<?xml version="1.0" encoding="UTF-8"?><cxmlconf><head>'
|
|
|
|
|
'<ver>{version}</ver>'
|
|
|
|
|
'<format>{type_doc}</format>'
|
|
|
|
|
'</head><body> </body></cxmlconf>'.format(version=version,
|
|
|
|
|
'</head><body></body></cxmlconf>'.format(version=version,
|
|
|
|
|
type_doc=typeDoc))
|
|
|
|
|
# self.doc = minidom.parseString(docTxt)
|
|
|
|
|
# self.root = self.doc.documentElement
|
|
|
|
@ -225,7 +256,10 @@ class xmlDoc(object):
|
|
|
|
|
# print(ET.tostring(self.doc, pretty_print=True))
|
|
|
|
|
# print(ET.tostring(self.body, pretty_print=True))
|
|
|
|
|
# установка разделителя областей
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.sepAreas = self.createField("br", [], "", [], False, False)
|
|
|
|
|
|
|
|
|
|
# установка разделителя областей разделенных списков
|
|
|
|
|
# self.sepSplitFields = self.createField("br",[],"",[],False,False)
|
|
|
|
|
return self.doc
|
|
|
|
@ -292,7 +326,7 @@ class xmlDoc(object):
|
|
|
|
|
def setActionField(self, xmlField, actionTxt):
|
|
|
|
|
"""Устанавливает свойство action для XML поля"""
|
|
|
|
|
xmlActions = xpath.Evaluate('child::action', xmlField)
|
|
|
|
|
if firstChild(xmlActions and xmlActions[0]):
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]) is not None:
|
|
|
|
|
firstChild(xmlActions[0]).text = actionTxt
|
|
|
|
|
else:
|
|
|
|
|
nodeObj = xmlNode()
|
|
|
|
@ -303,7 +337,7 @@ class xmlDoc(object):
|
|
|
|
|
"""Устанавливает свойство action для XML области"""
|
|
|
|
|
xmlActions = xpath.Evaluate('child::caption/action', xmlArea)
|
|
|
|
|
xmlCaptions = xpath.Evaluate('child::caption', xmlArea)
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]):
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]) is not None:
|
|
|
|
|
firstChild(xmlActions[0]).text = actionTxt
|
|
|
|
|
else:
|
|
|
|
|
if xmlCaptions:
|
|
|
|
@ -476,7 +510,7 @@ class xmlDoc(object):
|
|
|
|
|
"""Удаляет комментарии в XML области"""
|
|
|
|
|
fieldNodes = xpath.Evaluate('descendant::field', xmlArea)
|
|
|
|
|
for fieldNode in fieldNodes:
|
|
|
|
|
if fieldNode.get("type"):
|
|
|
|
|
if fieldNode.get("type") is not None:
|
|
|
|
|
if fieldNode.get("type") == "comment" or \
|
|
|
|
|
fieldNode.get("type") == "br":
|
|
|
|
|
parentNode = fieldNode.getparent()
|
|
|
|
@ -491,9 +525,18 @@ class xmlDoc(object):
|
|
|
|
|
|
|
|
|
|
def joinBody(self, baseBody, newBody):
|
|
|
|
|
"""Объединяет две области Body"""
|
|
|
|
|
# print("baseBody")
|
|
|
|
|
# display(baseBody)
|
|
|
|
|
# print("newBody")
|
|
|
|
|
# display(newBody)
|
|
|
|
|
newFields = xpath.Evaluate('child::field', newBody)
|
|
|
|
|
# if(newFields):
|
|
|
|
|
# print("newFields")
|
|
|
|
|
# display(newFields[0])
|
|
|
|
|
xmlNewAreas = xpath.Evaluate('child::area', newBody)
|
|
|
|
|
for xmlNewArea in xmlNewAreas:
|
|
|
|
|
for i, xmlNewArea in enumerate(xmlNewAreas):
|
|
|
|
|
# print("xmlNewArea ", i)
|
|
|
|
|
# display(xmlNewArea)
|
|
|
|
|
self.joinArea(baseBody, xmlNewArea)
|
|
|
|
|
joinNewFields = xpath.Evaluate("child::field[child::action='join']",
|
|
|
|
|
newBody)
|
|
|
|
@ -676,7 +719,10 @@ class xmlDoc(object):
|
|
|
|
|
self.setActionArea(xmlNewArea, "append")
|
|
|
|
|
# Добавляем разделитель областей во вложенные области
|
|
|
|
|
areaNodes = xpath.Evaluate('descendant::area', xmlNewArea)
|
|
|
|
|
# print("DEBUG appendArea")
|
|
|
|
|
# print(len(areaNodes))
|
|
|
|
|
for areaNode in areaNodes:
|
|
|
|
|
# display(areaNode)
|
|
|
|
|
self.setActionArea(areaNode, "append")
|
|
|
|
|
parentNode = areaNode.getparent()
|
|
|
|
|
insertBefore(parentNode, deepcopy(self.sepAreas),
|
|
|
|
@ -687,6 +733,10 @@ class xmlDoc(object):
|
|
|
|
|
|
|
|
|
|
nodesNames = xpath.Evaluate('child::area/caption/name', baseNode)
|
|
|
|
|
nodesNewArea = xpath.Evaluate('child::caption/name', xmlNewArea)
|
|
|
|
|
# print("nodesNames")
|
|
|
|
|
# print(nodesNames)
|
|
|
|
|
# print('nodesNewArea')
|
|
|
|
|
# print(nodesNewArea)
|
|
|
|
|
if not nodesNames:
|
|
|
|
|
# Добавляем область
|
|
|
|
|
if nodesNewArea:
|
|
|
|
@ -697,17 +747,29 @@ class xmlDoc(object):
|
|
|
|
|
if not nodesNames or not nodesNewArea:
|
|
|
|
|
return False
|
|
|
|
|
nameArea = ""
|
|
|
|
|
if firstChild(nodesNewArea[0]):
|
|
|
|
|
if firstChild(nodesNewArea[0]) is not None:
|
|
|
|
|
# print("HELLO")
|
|
|
|
|
|
|
|
|
|
nameArea = firstChild(nodesNewArea[0]).text.strip()
|
|
|
|
|
# print('nameArea: ', nameArea)
|
|
|
|
|
# print(firstChild(nodesNewArea[0]))
|
|
|
|
|
flagFindArea = False
|
|
|
|
|
newAreaAction = None
|
|
|
|
|
baseNodes = []
|
|
|
|
|
for oName in nodesNames:
|
|
|
|
|
# print("DEBUG in for oName")
|
|
|
|
|
# print(oName)
|
|
|
|
|
# display(oName)
|
|
|
|
|
# print(firstChild(oName))
|
|
|
|
|
newAreaAction = self.getActionArea(xmlNewArea)
|
|
|
|
|
oArea = oName.getparent().getparent()
|
|
|
|
|
oNameTxt = ""
|
|
|
|
|
if firstChild(oName):
|
|
|
|
|
|
|
|
|
|
if firstChild(oName) is not None:
|
|
|
|
|
|
|
|
|
|
oNameTxt = firstChild(oName).text
|
|
|
|
|
# print("BBBBBBBBBB")
|
|
|
|
|
# print(oNameTxt)
|
|
|
|
|
if nameArea == oNameTxt:
|
|
|
|
|
flagFindArea = True
|
|
|
|
|
# При использовании удаления
|
|
|
|
@ -728,10 +790,13 @@ class xmlDoc(object):
|
|
|
|
|
oldAreaCaption = xpath.Evaluate('child::caption',
|
|
|
|
|
oldAreaNode)[0]
|
|
|
|
|
if newAreaCaption and oldAreaCaption:
|
|
|
|
|
xmlNewArea.replaceChild(oldAreaCaption, newAreaCaption)
|
|
|
|
|
#its was replace(old, new) in legacy code, even though
|
|
|
|
|
#the func takes (new, old). Mistake, or on purpose?
|
|
|
|
|
#xmlNewArea.replaceChild(oldAreaCaption, newAreaCaption)
|
|
|
|
|
|
|
|
|
|
xmlNewArea.replace(newAreaCaption, oldAreaCaption)
|
|
|
|
|
self.setActionArea(xmlNewArea, "replace")
|
|
|
|
|
baseNode.replaceChild(xmlNewArea,
|
|
|
|
|
oldAreaNode)
|
|
|
|
|
baseNode.replace(oldAreaNode, xmlNewArea)
|
|
|
|
|
continue
|
|
|
|
|
baseNodes.append(oName.getparent().getparent())
|
|
|
|
|
newFields = xpath.Evaluate('child::field', xmlNewArea)
|
|
|
|
@ -742,6 +807,7 @@ class xmlDoc(object):
|
|
|
|
|
self.addNewFielsOldArea(newFields, joinNewFields, oArea)
|
|
|
|
|
|
|
|
|
|
if not flagFindArea:
|
|
|
|
|
# print("FLAG")
|
|
|
|
|
# Добавляем область
|
|
|
|
|
if not (newAreaAction == "drop" or newAreaAction == "replace"):
|
|
|
|
|
appendArea(baseNode, xmlNewArea)
|
|
|
|
@ -754,18 +820,20 @@ class xmlDoc(object):
|
|
|
|
|
|
|
|
|
|
def joinDoc(self, xmlNewDoc):
|
|
|
|
|
"""Объединяет два документа"""
|
|
|
|
|
# newRootNode = xmlNewDoc.documentElement
|
|
|
|
|
newRootNode = xmlNewDoc.getroottree()
|
|
|
|
|
newBodyNode = xpath.Evaluate('child::body', newRootNode)[0]
|
|
|
|
|
# newImportBodyNode = self.doc.importNode(newBodyNode, True)
|
|
|
|
|
newImportBodyNode = deepcopy(newBodyNode)
|
|
|
|
|
|
|
|
|
|
# Перед объединение области с документом
|
|
|
|
|
# удаляем комментарии
|
|
|
|
|
|
|
|
|
|
self.removeComment(newImportBodyNode)
|
|
|
|
|
self.joinBody(self.body, newImportBodyNode)
|
|
|
|
|
# расставляем BR
|
|
|
|
|
self.insertBRtoBody(self.body)
|
|
|
|
|
# print("final:")
|
|
|
|
|
# display(self.doc)
|
|
|
|
|
# print("--------------------------------")
|
|
|
|
|
|
|
|
|
|
def getQuoteField(self, xmlField):
|
|
|
|
|
"""Выдает текст из поля"""
|
|
|
|
@ -775,7 +843,7 @@ class xmlDoc(object):
|
|
|
|
|
br = "\n"
|
|
|
|
|
if xmlQuotes:
|
|
|
|
|
field = xmlQuotes[0]
|
|
|
|
|
if firstChild(field):
|
|
|
|
|
if firstChild(field) is not None:
|
|
|
|
|
return firstChild(field).text + br
|
|
|
|
|
return "" + br
|
|
|
|
|
|
|
|
|
@ -799,7 +867,7 @@ class xmlDoc(object):
|
|
|
|
|
def getNameField(self, xmlField):
|
|
|
|
|
"""Выдает имя поля"""
|
|
|
|
|
xmlNameFields = xpath.Evaluate('child::name', xmlField)
|
|
|
|
|
if xmlNameFields and firstChild(xmlNameFields[0]):
|
|
|
|
|
if xmlNameFields and firstChild(xmlNameFields[0]) is not None:
|
|
|
|
|
return firstChild(xmlNameFields[0]).text
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
@ -819,7 +887,7 @@ class xmlDoc(object):
|
|
|
|
|
quotes = []
|
|
|
|
|
xmlQuotes = xpath.Evaluate('child::caption/quote', xmlArea)
|
|
|
|
|
for node in xmlQuotes:
|
|
|
|
|
if firstChild(node):
|
|
|
|
|
if firstChild(node) is not None:
|
|
|
|
|
quotes.append(firstChild(node).text)
|
|
|
|
|
if len(quotes) == 0:
|
|
|
|
|
quotes.append("")
|
|
|
|
@ -855,7 +923,7 @@ class xmlDoc(object):
|
|
|
|
|
def getActionField(self, xmlField):
|
|
|
|
|
"""Выдает свойство action XML поля"""
|
|
|
|
|
xmlActions = xpath.Evaluate('child::action', xmlField)
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]):
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]) is not None:
|
|
|
|
|
return firstChild(xmlActions[0]).text
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
@ -866,14 +934,14 @@ class xmlDoc(object):
|
|
|
|
|
xmlValues = xpath.Evaluate('child::value', xmlField)
|
|
|
|
|
if xmlValues:
|
|
|
|
|
for node in xmlValues:
|
|
|
|
|
if firstChild(node):
|
|
|
|
|
if firstChild(node) is not None:
|
|
|
|
|
vals.append(firstChild(node).text)
|
|
|
|
|
return vals
|
|
|
|
|
|
|
|
|
|
def getActionArea(self, xmlArea):
|
|
|
|
|
"""Выдает свойство action XML области"""
|
|
|
|
|
xmlActions = xpath.Evaluate('child::caption/action', xmlArea)
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]):
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]) is not None:
|
|
|
|
|
return firstChild(xmlActions[0]).text
|
|
|
|
|
else:
|
|
|
|
|
return False
|
|
|
|
@ -881,7 +949,7 @@ class xmlDoc(object):
|
|
|
|
|
def delActionNodeArea(self, xmlArea):
|
|
|
|
|
"""Удаляет свойство action XML области"""
|
|
|
|
|
xmlActions = xpath.Evaluate('child::caption/action', xmlArea)
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]):
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]) is not None:
|
|
|
|
|
parentNode = xmlActions[0].getparent()
|
|
|
|
|
parentNode.remove(xmlActions[0])
|
|
|
|
|
return True
|
|
|
|
@ -891,7 +959,7 @@ class xmlDoc(object):
|
|
|
|
|
def delActionNodeField(self, xmlField):
|
|
|
|
|
"""Удаляет свойство action XML поля"""
|
|
|
|
|
xmlActions = xpath.Evaluate('child::action', xmlField)
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]):
|
|
|
|
|
if xmlActions and firstChild(xmlActions[0]) is not None:
|
|
|
|
|
parentNode = xmlActions[0].getparent()
|
|
|
|
|
parentNode.remove(xmlActions[0])
|
|
|
|
|
return True
|
|
|
|
@ -931,10 +999,12 @@ class xmlDoc(object):
|
|
|
|
|
childNodes = self.getFieldsArea(xmlArea)
|
|
|
|
|
# нода BR
|
|
|
|
|
fieldXMLBr = self.createField("br", [], "", [], False, False)
|
|
|
|
|
|
|
|
|
|
# Предыдущая нода
|
|
|
|
|
lastNode = False
|
|
|
|
|
lastNode = None
|
|
|
|
|
lenChildNodes = len(childNodes)
|
|
|
|
|
for i in range(lenChildNodes):
|
|
|
|
|
# print(lastNode)
|
|
|
|
|
node = childNodes[i]
|
|
|
|
|
lastTmpNode = node
|
|
|
|
|
# Нода area
|
|
|
|
@ -942,8 +1012,8 @@ class xmlDoc(object):
|
|
|
|
|
if self.getActionArea(node) == "append" or \
|
|
|
|
|
self.getActionArea(node) == "join":
|
|
|
|
|
self.delActionNodeArea(node)
|
|
|
|
|
if lastNode and lastNode.get("type") == "br" or \
|
|
|
|
|
lastNode and lastNode.get("type") == "comment":
|
|
|
|
|
if lastNode is not None and lastNode.get("type") == "br" or \
|
|
|
|
|
lastNode is not None and lastNode.get("type") == "comment":
|
|
|
|
|
indNext = i + 1
|
|
|
|
|
if indNext == lenChildNodes:
|
|
|
|
|
xmlArea.append(deepcopy(fieldXMLBr))
|
|
|
|
@ -1013,7 +1083,7 @@ class xmlDoc(object):
|
|
|
|
|
if flagListXml:
|
|
|
|
|
nameNode = xpath.Evaluate('child::caption/name', xmlArea)[0]
|
|
|
|
|
fieldName = ""
|
|
|
|
|
if firstChild(nameNode):
|
|
|
|
|
if firstChild(nameNode) is not None:
|
|
|
|
|
fieldName = firstChild(nameNode).text
|
|
|
|
|
listArea = []
|
|
|
|
|
self.xmlToText([xmlArea], listArea)
|
|
|
|
|