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 | ||||
| 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>' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user