facho placeholder mantiene orden de elementos
FossilOrigin-Name: c535b486c8f956a25f8e88bf9053aab312ed441b1d217699a36924e24b46ab21
This commit is contained in:
parent
adbd6d0d0e
commit
7f72bab06a
@ -5,6 +5,7 @@ from lxml import etree
|
|||||||
from lxml.etree import Element, SubElement, tostring
|
from lxml.etree import Element, SubElement, tostring
|
||||||
import re
|
import re
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from copy import deepcopy
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
class FachoValueInvalid(Exception):
|
class FachoValueInvalid(Exception):
|
||||||
@ -114,9 +115,18 @@ class LXMLBuilder:
|
|||||||
elem.attrib[key] = value
|
elem.attrib[key] = value
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tostring(self, elem, **attrs):
|
def tostring(self, oelem, **attrs):
|
||||||
|
elem = deepcopy(oelem)
|
||||||
|
|
||||||
attrs['pretty_print'] = attrs.pop('pretty_print', False)
|
attrs['pretty_print'] = attrs.pop('pretty_print', False)
|
||||||
attrs['encoding'] = attrs.pop('encoding', 'UTF-8')
|
attrs['encoding'] = attrs.pop('encoding', 'UTF-8')
|
||||||
|
|
||||||
|
for el in elem.getiterator():
|
||||||
|
is_optional = el.get('facho_optional', 'False') == 'True'
|
||||||
|
if is_optional and el.getchildren() == []:
|
||||||
|
print(tostring(el))
|
||||||
|
el.getparent().remove(el)
|
||||||
|
|
||||||
return tostring(elem, **attrs).decode('utf-8')
|
return tostring(elem, **attrs).decode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
@ -182,8 +192,11 @@ class FachoXML:
|
|||||||
def _path_xpath_for(self, xpath):
|
def _path_xpath_for(self, xpath):
|
||||||
return self._normalize_xpath(self._translate_xpath_for(xpath))
|
return self._normalize_xpath(self._translate_xpath_for(xpath))
|
||||||
|
|
||||||
def placeholder_for(self, xpath, append=False):
|
def placeholder_for(self, xpath, append=False, optional=False):
|
||||||
return self.find_or_create_element(xpath, append)
|
elem = self.find_or_create_element(xpath, append)
|
||||||
|
if optional:
|
||||||
|
elem.set('facho_optional', 'True')
|
||||||
|
return elem
|
||||||
|
|
||||||
def replacement_for(self, xpath, new_xpath, content, **attrs):
|
def replacement_for(self, xpath, new_xpath, content, **attrs):
|
||||||
elem = self.get_element(xpath)
|
elem = self.get_element(xpath)
|
||||||
@ -217,6 +230,7 @@ class FachoXML:
|
|||||||
for node_path in node_paths:
|
for node_path in node_paths:
|
||||||
node_expr = self.builder.match_expression(node_path)
|
node_expr = self.builder.match_expression(node_path)
|
||||||
node = self.builder.build_from_expression(node_path)
|
node = self.builder.build_from_expression(node_path)
|
||||||
|
|
||||||
child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap)
|
child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap)
|
||||||
|
|
||||||
parent = current_elem
|
parent = current_elem
|
||||||
@ -240,6 +254,12 @@ class FachoXML:
|
|||||||
self.builder.append_next(last_slibing, node)
|
self.builder.append_next(last_slibing, node)
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
try:
|
||||||
|
# TODO(bit4bit) acoplamiento indirecto a placeholder
|
||||||
|
del current_elem.attrib['facho_optional']
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
return current_elem
|
return current_elem
|
||||||
|
|
||||||
def set_element_validator(self, xpath, validator = False):
|
def set_element_validator(self, xpath, validator = False):
|
||||||
@ -267,6 +287,7 @@ class FachoXML:
|
|||||||
format_ = attrs.pop('format_', '%s')
|
format_ = attrs.pop('format_', '%s')
|
||||||
append_ = attrs.pop('append_', False)
|
append_ = attrs.pop('append_', False)
|
||||||
elem = self.find_or_create_element(xpath, append=append_)
|
elem = self.find_or_create_element(xpath, append=append_)
|
||||||
|
|
||||||
validator = self._validators[xpath]
|
validator = self._validators[xpath]
|
||||||
|
|
||||||
if not validator(content, attrs):
|
if not validator(content, attrs):
|
||||||
|
@ -219,3 +219,39 @@ def test_facho_xml_keep_orden_slibing():
|
|||||||
xml.find_or_create_element('./A', append=True)
|
xml.find_or_create_element('./A', append=True)
|
||||||
|
|
||||||
assert xml.tostring() == '<root><A/><A/><B/><B/><C/></root>'
|
assert xml.tostring() == '<root><A/><A/><B/><B/><C/></root>'
|
||||||
|
|
||||||
|
def test_facho_xml_placeholder_optional():
|
||||||
|
xml = facho.FachoXML('root')
|
||||||
|
xml.placeholder_for('./A')
|
||||||
|
xml.placeholder_for('./B', optional=True)
|
||||||
|
xml.placeholder_for('./C')
|
||||||
|
|
||||||
|
assert xml.tostring() == '<root><A/><C/></root>'
|
||||||
|
|
||||||
|
def test_facho_xml_placeholder_append_to_optional():
|
||||||
|
xml = facho.FachoXML('root')
|
||||||
|
xml.placeholder_for('./A')
|
||||||
|
xml.placeholder_for('./B', optional=True)
|
||||||
|
xml.placeholder_for('./C')
|
||||||
|
|
||||||
|
xml.find_or_create_element('./B')
|
||||||
|
assert xml.tostring() == '<root><A/><B/><C/></root>'
|
||||||
|
|
||||||
|
def test_facho_xml_placeholder_set_element_to_optional():
|
||||||
|
xml = facho.FachoXML('root')
|
||||||
|
xml.placeholder_for('./A')
|
||||||
|
xml.placeholder_for('./B', optional=True)
|
||||||
|
xml.placeholder_for('./C')
|
||||||
|
|
||||||
|
xml.set_element('./B', '2')
|
||||||
|
assert xml.tostring() == '<root><A/><B>2</B><C/></root>'
|
||||||
|
|
||||||
|
def test_facho_xml_placeholder_set_element_to_optional_with_append():
|
||||||
|
xml = facho.FachoXML('root')
|
||||||
|
xml.placeholder_for('./A')
|
||||||
|
xml.placeholder_for('./B', optional=True)
|
||||||
|
xml.placeholder_for('./C')
|
||||||
|
|
||||||
|
xml.set_element('./B', '2')
|
||||||
|
xml.set_element('./B', '3', append_=True)
|
||||||
|
assert xml.tostring() == '<root><A/><B>2</B><B>3</B><C/></root>'
|
||||||
|
Loading…
Reference in New Issue
Block a user