diff --git a/pydantic_xml/element/element.py b/pydantic_xml/element/element.py index 2a27862..5b65a0c 100644 --- a/pydantic_xml/element/element.py +++ b/pydantic_xml/element/element.py @@ -257,6 +257,7 @@ def set_attributes(self, attributes: Dict[str, str]) -> None: def append_element(self, element: 'XmlElement[NativeElement]') -> None: self._state.elements.append(element) + self._state.next_element_idx += 1 def pop_text(self) -> Optional[str]: result, self._state.text = self._state.text, None @@ -295,6 +296,7 @@ def find_element_or_create( if (sub_element := self._find_element(tag, search_mode)) is None: sub_element = self.make_element(tag=tag, nsmap=nsmap) self._state.elements.append(sub_element) + self._state.next_element_idx += 1 return sub_element diff --git a/tests/test_wrapped.py b/tests/test_wrapped.py index ca2dfbf..212020c 100644 --- a/tests/test_wrapped.py +++ b/tests/test_wrapped.py @@ -7,18 +7,54 @@ def test_wrapped_primitive_extraction(): class TestModel(BaseXmlModel, tag='model1'): + element0: str = element(tag='element') data: int = wrapped('model2') - attr1: int = wrapped('model2', attr()) + attr1: int = wrapped('model2', attr(name='attr1')) element1: int = wrapped('model2', element()) xml = ''' + text 13 ''' actual_obj = TestModel.from_xml(xml) - expected_obj = TestModel(data=1, attr1=2, element1=3) + expected_obj = TestModel(element0="text", data=1, attr1=2, element1=3) + + assert actual_obj == expected_obj + + actual_xml = actual_obj.to_xml() + assert_xml_equal(actual_xml, xml) + + +def test_wrapped_path_merge(): + class TestModel(BaseXmlModel, tag='model1'): + element0: int = element(tag='element0') + element1: int = element(tag='element1') + attr0: int = wrapped('element1', attr(name='attr')) + element2: int = wrapped('element2/element3', element(tag='element4')) + element3: int = wrapped('element2/element3', element(tag='element5')) + attr1: int = wrapped('element2/element6', attr(name='attr')) + element4: int = element(tag='element7') + + xml = ''' + + 0 + 1 + + + 3 + 4 + + + + 6 + + ''' + + actual_obj = TestModel.from_xml(xml) + expected_obj = TestModel(element0=0, element1=1, attr0=2, element2=3, element3=4, attr1=5, element4=6) assert actual_obj == expected_obj @@ -214,3 +250,27 @@ class TestModel(BaseXmlModel, tag='model1'): actual_xml = actual_obj.to_xml() assert_xml_equal(actual_xml, xml) + + +def test_wrapped_root(): + class TestSubModel(BaseXmlModel, tag='model3'): + attr1: int = attr() + + class TestModel(BaseXmlModel, tag='model1'): + __root__: TestSubModel = wrapped('model2') + + xml = ''' + + + + + + ''' + + actual_obj = TestModel.from_xml(xml) + expected_obj = TestModel(__root__=TestSubModel(attr1=1)) + + assert actual_obj == expected_obj + + actual_xml = actual_obj.to_xml() + assert_xml_equal(actual_xml, xml)