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
|
||||
import re
|
||||
from collections import defaultdict
|
||||
from copy import deepcopy
|
||||
from pprint import pprint
|
||||
|
||||
class FachoValueInvalid(Exception):
|
||||
@ -114,9 +115,18 @@ class LXMLBuilder:
|
||||
elem.attrib[key] = value
|
||||
|
||||
@classmethod
|
||||
def tostring(self, elem, **attrs):
|
||||
def tostring(self, oelem, **attrs):
|
||||
elem = deepcopy(oelem)
|
||||
|
||||
attrs['pretty_print'] = attrs.pop('pretty_print', False)
|
||||
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')
|
||||
|
||||
|
||||
@ -182,8 +192,11 @@ class FachoXML:
|
||||
def _path_xpath_for(self, xpath):
|
||||
return self._normalize_xpath(self._translate_xpath_for(xpath))
|
||||
|
||||
def placeholder_for(self, xpath, append=False):
|
||||
return self.find_or_create_element(xpath, append)
|
||||
def placeholder_for(self, xpath, append=False, optional=False):
|
||||
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):
|
||||
elem = self.get_element(xpath)
|
||||
@ -217,6 +230,7 @@ class FachoXML:
|
||||
for node_path in node_paths:
|
||||
node_expr = self.builder.match_expression(node_path)
|
||||
node = self.builder.build_from_expression(node_path)
|
||||
|
||||
child = self.builder.find_relative(current_elem, node_expr['path'], self.nsmap)
|
||||
|
||||
parent = current_elem
|
||||
@ -240,6 +254,12 @@ class FachoXML:
|
||||
self.builder.append_next(last_slibing, node)
|
||||
return node
|
||||
|
||||
try:
|
||||
# TODO(bit4bit) acoplamiento indirecto a placeholder
|
||||
del current_elem.attrib['facho_optional']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
return current_elem
|
||||
|
||||
def set_element_validator(self, xpath, validator = False):
|
||||
@ -267,6 +287,7 @@ class FachoXML:
|
||||
format_ = attrs.pop('format_', '%s')
|
||||
append_ = attrs.pop('append_', False)
|
||||
elem = self.find_or_create_element(xpath, append=append_)
|
||||
|
||||
validator = self._validators[xpath]
|
||||
|
||||
if not validator(content, attrs):
|
||||
|
@ -219,3 +219,39 @@ def test_facho_xml_keep_orden_slibing():
|
||||
xml.find_or_create_element('./A', append=True)
|
||||
|
||||
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