facho placeholder mantiene orden de elementos
FossilOrigin-Name: c535b486c8f956a25f8e88bf9053aab312ed441b1d217699a36924e24b46ab21
This commit is contained in:
		| @@ -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>' | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user