Convert the Blocks into an XML document
| 30 | |
| 31 | @dc.dataclass |
| 32 | class XMLBuilder(ViewVisitor): |
| 33 | """Convert the Blocks into an XML document""" |
| 34 | |
| 35 | store: FileStore |
| 36 | # element: t.Optional[etree.Element] = None # Empty Group Element? |
| 37 | elements: t.List[ElementT] = dc.field(default_factory=list) |
| 38 | |
| 39 | def get_root(self, fragment: bool = False) -> ElementT: |
| 40 | """Return the top-level ViewXML""" |
| 41 | # create the top-level |
| 42 | |
| 43 | # get the top-level root |
| 44 | _top_group: ElementT = self.elements.pop() |
| 45 | assert _top_group.tag == "Group" |
| 46 | assert not self.elements |
| 47 | |
| 48 | # create top-level structure |
| 49 | return E.View( |
| 50 | # E.Internal(), |
| 51 | *_top_group.getchildren(), |
| 52 | **mk_attribs(version="1", fragment=fragment), |
| 53 | ) |
| 54 | |
| 55 | @property |
| 56 | def store_count(self) -> int: |
| 57 | return len(self.store.files) |
| 58 | |
| 59 | def add_element(self, _: BaseBlock, e: etree.Element) -> XMLBuilder: |
| 60 | """Add an element to the list of nodes at the current XML tree location""" |
| 61 | self.elements.append(e) |
| 62 | return self |
| 63 | |
| 64 | # xml convertors |
| 65 | @multimethod |
| 66 | def visit(self, b: BaseBlock) -> XMLBuilder: |
| 67 | """Base implementation - just created an empty tag including all the initial attributes""" |
| 68 | _E = getattr(E, b._tag) |
| 69 | return self.add_element(b, _E(**b._attributes)) |
| 70 | |
| 71 | def _visit_subnodes(self, b: ContainerBlock) -> t.List[ElementT]: |
| 72 | cur_elements = self.elements |
| 73 | self.elements = [] |
| 74 | b.traverse(self) # visit subnodes |
| 75 | res = self.elements |
| 76 | self.elements = cur_elements |
| 77 | return res |
| 78 | |
| 79 | @multimethod |
| 80 | def visit(self, b: ContainerBlock) -> XMLBuilder: |
| 81 | sub_elements = self._visit_subnodes(b) |
| 82 | # build the element |
| 83 | _E = getattr(E, b._tag) |
| 84 | element = _E(*sub_elements, **b._attributes) |
| 85 | return self.add_element(b, element) |
| 86 | |
| 87 | @multimethod |
| 88 | def visit(self, b: Blocks) -> XMLBuilder: |
| 89 | sub_elements = self._visit_subnodes(b) |
no outgoing calls
no test coverage detected