def dumps(root_element, *, format=False) -> str: """Serialize a SDFormat object to an XML string. Parameters ---------- root_element : object An instance of ``skbot.ignition.models.vXX.Sdf``. XX represents the SDFormat version and can be any version currently supported by scikit-bot. format : bool If true, add indentation and linebreaks to the output to increase human readability. If false (default) the entire XML will appear as a single line with no spaces between elements. Returns ------- sdformat_string : str A string containing SDFormat XML representing the given input. Examples -------- .. minigallery:: skbot.ignition.sdformat.dumps """ serializer = XmlSerializer(config=SerializerConfig(pretty_print=format)) return serializer.render(root_element)
def test_render_with_provided_namespaces(self): serializer = XmlSerializer(pretty_print=True) namespaces = Namespaces() namespaces.add("urn:books", "burn") actual = serializer.render(self.books, namespaces) expected = ( "<?xml version='1.0' encoding='UTF-8'?>\n" '<burn:books xmlns:burn="urn:books">\n' ' <book id="bk001" lang="en">\n' " <author>Hightower, Kim</author>\n" " <title>The First Book</title>\n" " <genre>Fiction</genre>\n" " <price>44.95</price>\n" " <pub_date>2000-10-01</pub_date>\n" " <review>An amazing story of nothing.</review>\n" " </book>\n" ' <book id="bk002" lang="en">\n' " <author>Nagata, Suanne</author>\n" " <title>Becoming Somebody</title>\n" " <genre>Biography</genre>\n" " <review>A masterpiece of the fine art of gossiping.</review>\n" " </book>\n" "</burn:books>\n") self.assertEqual(expected, actual)
def serialize(obj: object, pretty_print: bool = False) -> str: ns_map = __get_ns_map(obj) schema_location = __get_ns_schema_location(obj) config = SerializerConfig(xml_version='1.0', encoding='UTF-8', schema_location=schema_location, pretty_print=pretty_print) serializer = XmlSerializer(config=config) return serializer.render(obj, ns_map=ns_map)
def writer(xrnsfile, song): xrns = XrnsSerializer() xml_song = xrns.render(song) config = SerializerConfig(pretty_print=True, encoding="UTF-8", xml_version="1.0") serializer = XmlSerializer(config=config) # , writer=XmlEventWriter) rendered = serializer.render(xml_song) with zipfile.ZipFile(xrnsfile, mode="w") as zf: zf.writestr("Song.xml", rendered)
class LxmlEventWriterTests(TestCase): def setUp(self): config = SerializerConfig(pretty_print=True) self.serializer = XmlSerializer(config=config, writer=LxmlEventWriter) def test_render(self): actual = self.serializer.render(books) expected = fixtures_dir.joinpath("books/books_auto_ns.xml").read_text() self.assertEqual(expected, actual) def test_render_with_provided_namespaces(self): actual = self.serializer.render(books, {"brk": "urn:books"}) expected = fixtures_dir.joinpath("books/books.xml").read_text() self.assertEqual(expected, actual) def test_render_with_default_namespace_prefix(self): actual = self.serializer.render(books, {None: "urn:books"}) expected = fixtures_dir.joinpath( "books/books_default_ns.xml").read_text() xml_declaration, actual = actual.split("\n", 1) _, expected = expected.split("\n", 1) self.assertEqual(expected, actual) def test_encoding(self): self.serializer.config.encoding = "US-ASCII" self.serializer.config.xml_version = "1.1" actual = self.serializer.render(books) xml_declaration, _ = actual.split("\n", 1) self.assertEqual('<?xml version="1.1" encoding="US-ASCII"?>', xml_declaration) def test_declaration_disabled(self): self.serializer.config.xml_declaration = False actual = self.serializer.render(books, {None: "urn:books"}) expected = fixtures_dir.joinpath( "books/books_default_ns.xml").read_text() xml_declaration, expected = expected.split("\n", 1) self.assertEqual(expected, actual) def test_pretty_print_false(self): self.serializer.config.pretty_print = False actual = self.serializer.render(books) expected = fixtures_dir.joinpath("books/books_auto_ns.xml").read_text() _, actual = actual.split("\n", 1) _, expected = expected.split("\n", 1) self.assertEqual(expected.replace(" ", "").replace("\n", ""), actual)
def test_xml_documents(): filepath = fixtures_dir.joinpath("artists") package = "tests.fixtures.artists" runner = CliRunner() result = runner.invoke(cli, [str(filepath), "--package", package]) if result.exception: raise result.exception clazz = load_class(result.output, "Metadata") parser = XmlParser() serializer = XmlSerializer(writer=XmlEventWriter) serializer.config.pretty_print = True serializer.config.xml_declaration = False ns_map = {None: "http://musicbrainz.org/ns/mmd-2.0#"} for i in range(1, 4): ap = filepath.joinpath(f"art00{i}.xml") obj = parser.from_path(ap, clazz) actual = serializer.render(obj, ns_map) assert ap.read_bytes().splitlines() == actual.encode().splitlines()
class XmlSerializerTests(TestCase): def setUp(self): super(XmlSerializerTests, self).setUp() self.serializer = XmlSerializer(pretty_print=True) self.namespaces = Namespaces() self.books = Books( book=[ BookForm( id="bk001", author="Hightower, Kim", title="The First Book", genre="Fiction", price=44.95, pub_date="2000-10-01", review="An amazing story of nothing.", ), BookForm( id="bk002", author="Nagata, Suanne", title="Becoming Somebody", genre="Biography", review="A masterpiece of the fine art of gossiping.", ), ] ) def test_render(self): actual = self.serializer.render(self.books) expected = ( "<?xml version='1.0' encoding='UTF-8'?>\n" '<ns0:books xmlns:ns0="urn:books">\n' ' <book id="bk001" lang="en">\n' " <author>Hightower, Kim</author>\n" " <title>The First Book</title>\n" " <genre>Fiction</genre>\n" " <price>44.95</price>\n" " <pub_date>2000-10-01</pub_date>\n" " <review>An amazing story of nothing.</review>\n" " </book>\n" ' <book id="bk002" lang="en">\n' " <author>Nagata, Suanne</author>\n" " <title>Becoming Somebody</title>\n" " <genre>Biography</genre>\n" " <review>A masterpiece of the fine art of gossiping.</review>\n" " </book>\n" "</ns0:books>\n" ) self.assertEqual(expected, actual) def test_render_with_provided_namespaces(self): self.namespaces.add("urn:books", "burn") actual = self.serializer.render(self.books, self.namespaces) expected = ( "<?xml version='1.0' encoding='UTF-8'?>\n" '<burn:books xmlns:burn="urn:books">\n' ' <book id="bk001" lang="en">\n' " <author>Hightower, Kim</author>\n" " <title>The First Book</title>\n" " <genre>Fiction</genre>\n" " <price>44.95</price>\n" " <pub_date>2000-10-01</pub_date>\n" " <review>An amazing story of nothing.</review>\n" " </book>\n" ' <book id="bk002" lang="en">\n' " <author>Nagata, Suanne</author>\n" " <title>Becoming Somebody</title>\n" " <genre>Biography</genre>\n" " <review>A masterpiece of the fine art of gossiping.</review>\n" " </book>\n" "</burn:books>\n" ) self.assertEqual(expected, actual) def test_render_no_dataclass(self): with self.assertRaises(XmlContextError) as cm: self.serializer.render(self) self.assertEqual( f"Object {self.__class__} is not a dataclass.", str(cm.exception) ) @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(SerializeUtils, "set_text") @mock.patch.object(SerializeUtils, "set_attributes") @mock.patch.object(SerializeUtils, "set_attribute") @mock.patch.object(XmlSerializer, "render_sub_node") @mock.patch.object(XmlSerializer, "next_value") def test_render_node( self, mock_next_value, mock_render_sub_node, mock_set_attribute, mock_set_attributes, mock_set_text, mock_set_nil_attribute, ): root = Element("root") prod_meta = self.serializer.context.build(ProductType) size_meta = self.serializer.context.build(SizeType) obj = ProductType() attribute = prod_meta.find_var("effDate") attributes = prod_meta.find_var("{!}other_attributes") text = replace(size_meta.find_var("value"), qname=QName("foo", "bar")) sub_node = prod_meta.find_var("name") mock_next_value.return_value = [ (attribute, None), (attribute, 1), (attributes, dict(a=1)), (text, "txt"), (sub_node, 1), (sub_node, [2, 3]), ] self.serializer.render_node(root, obj, self.namespaces) self.assertEqual({"ns0": "foo"}, self.namespaces.ns_map) mock_set_attribute.assert_called_once_with( root, attribute.qname, 1, self.namespaces ) mock_set_attributes.assert_called_once_with(root, dict(a=1), self.namespaces) mock_set_text.assert_called_once_with(root, "txt", self.namespaces) mock_render_sub_node.assert_has_calls( [ mock.call(root, 1, sub_node, self.namespaces), mock.call(root, 2, sub_node, self.namespaces), mock.call(root, 3, sub_node, self.namespaces), ] ) mock_set_nil_attribute.assert_called_once_with(root, False, self.namespaces) def test_render_node_without_dataclass(self): root = Element("root") self.serializer.render_node(root, 1, self.namespaces) self.assertEqual("1", root.text) @mock.patch.object(XmlSerializer, "render_sub_node") def test_render_sub_nodes(self, mock_render_sub_node): root = Element("root") meta = self.serializer.context.build(ProductType) var = meta.find_var("number") self.serializer.render_sub_nodes(root, [1, 2, 3], var, self.namespaces) self.assertEqual(3, mock_render_sub_node.call_count) mock_render_sub_node.assert_has_calls( [ mock.call(root, 1, var, self.namespaces), mock.call(root, 2, var, self.namespaces), mock.call(root, 3, var, self.namespaces), ] ) @mock.patch.object(XmlSerializer, "render_wildcard_node") def test_render_sub_node_with_generic_object(self, mock_render_wildcard_node): root = Element("root") value = AnyElement() meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_render_wildcard_node.call_count) mock_render_wildcard_node.assert_called_once_with( root, value, var, self.namespaces ) @mock.patch.object(XmlSerializer, "render_element_node") def test_render_sub_node_with_xml_element(self, mock_render_element_node): root = Element("root") value = 1 meta = self.serializer.context.build(ProductType) var = meta.find_var("number") self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_render_element_node.call_count) mock_render_element_node.assert_called_once_with( root, value, var, self.namespaces ) @mock.patch.object(XmlSerializer, "render_element_node") def test_render_sub_node_with_dataclass_object(self, mock_render_element_node): root = Element("root") value = SizeType() meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_render_element_node.call_count) mock_render_element_node.assert_called_once_with( root, value, var, self.namespaces ) @mock.patch.object(SerializeUtils, "set_tail") @mock.patch.object(SerializeUtils, "set_text") def test_render_sub_node_with_primitive_value_and_not_xml_element( self, mock_set_text, mock_set_tail ): root = Element("root") value = 1 meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_set_text.call_count) mock_set_text.assert_called_once_with(root, value, self.namespaces) root.text = "foo" self.serializer.render_sub_node(root, value, var, self.namespaces) self.assertEqual(1, mock_set_tail.call_count) mock_set_tail.assert_called_once_with(root, value, self.namespaces) @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(XmlSerializer, "set_xsi_type") @mock.patch.object(XmlSerializer, "render_node") def test_render_element_node( self, mock_render_node, mock_set_xsi_type, mock_set_nil_attribute ): root = Element("root") value = SizeType() meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_element_node(root, value, var, self.namespaces) child = root[0] mock_render_node.assert_called_once_with(child, value, self.namespaces) mock_set_xsi_type.assert_called_once_with(child, value, var, self.namespaces) mock_set_nil_attribute.assert_called_once_with( child, var.nillable, self.namespaces ) self.assertEqual(var.qname, child.tag) self.assertEqual( {"ns0": "http://www.w3.org/1999/xhtml"}, self.namespaces.ns_map ) @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(XmlSerializer, "render_node") def test_render_element_node_with_specific_qname( self, mock_render_node, mock_set_nil_attribute ): root = Element("root") value = SizeType() value.qname = "foo" meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_element_node(root, value, var, self.namespaces) child = root[0] mock_render_node.assert_called_once_with(child, value, self.namespaces) mock_set_nil_attribute.assert_called_once_with( child, var.nillable, self.namespaces ) self.assertEqual("foo", child.tag) self.assertEqual(0, len(self.namespaces.ns_map)) @mock.patch.object(XmlSerializer, "render_sub_node") @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(SerializeUtils, "set_attributes") @mock.patch.object(SerializeUtils, "set_tail") @mock.patch.object(SerializeUtils, "set_text") def test_render_wildcard_node( self, mock_set_text, mock_set_tail, mock_set_attributes, mock_set_nil_attribute, mock_render_sub_node, ): root = Element("root") value = AnyElement( text="foo", tail="bar", attributes=dict(a=1), children=[AnyElement(), AnyElement()], ns_map={"foo": "bar"}, qname="foo", ) meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_wildcard_node(root, value, var, self.namespaces) child = root[0] self.assertEqual({"foo": "bar"}, self.namespaces.ns_map) self.assertEqual(value.qname, child.tag) mock_set_text.assert_called_once_with(child, value.text, self.namespaces) mock_set_tail.assert_called_once_with(child, value.tail, self.namespaces) mock_set_attributes.assert_called_once_with( child, value.attributes, self.namespaces ) mock_render_sub_node.assert_has_calls( [ mock.call(child, value.children[0], var, self.namespaces), mock.call(child, value.children[1], var, self.namespaces), ] ) mock_set_nil_attribute.assert_called_once_with( child, var.nillable, self.namespaces ) @mock.patch.object(XmlSerializer, "render_sub_node") @mock.patch.object(SerializeUtils, "set_nil_attribute") @mock.patch.object(SerializeUtils, "set_attributes") @mock.patch.object(SerializeUtils, "set_tail") @mock.patch.object(SerializeUtils, "set_text") def test_render_wildcard_node_without_qname( self, mock_set_text, mock_set_tail, mock_set_attributes, mock_set_nil_attribute, mock_render_sub_node, ): root = Element("root") value = AnyElement( text="foo", tail="bar", attributes=dict(a=1), children=[AnyElement()] ) meta = self.serializer.context.build(DescriptionType) var = meta.find_var(mode=FindMode.WILDCARD) self.serializer.render_wildcard_node(root, value, var, self.namespaces) self.assertEqual(0, len(self.namespaces.ns_map)) self.assertEqual(0, len(root)) mock_set_text.assert_called_once_with(root, value.text, self.namespaces) mock_set_tail.assert_called_once_with(root, value.tail, self.namespaces) mock_set_attributes.assert_called_once_with( root, value.attributes, self.namespaces ) mock_render_sub_node.assert_called_once_with( root, value.children[0], var, self.namespaces ) mock_set_nil_attribute.assert_called_once_with( root, var.nillable, self.namespaces ) def test_set_xsi_type_with_non_dataclass(self): elem = Element("foo") value = 1 meta = self.serializer.context.build(ProductType) var = meta.find_var("number") self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertNotIn(QNames.XSI_TYPE, elem.attrib) def test_set_xsi_type_when_value_type_matches_var_clazz(self): elem = Element("foo") value = SizeType() meta = self.serializer.context.build(ProductType) var = meta.find_var("size") self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertNotIn(QNames.XSI_TYPE, elem.attrib) def test_set_xsi_type_when_value_is_not_derived_from_var_clazz(self): elem = Element("foo") value = ColorType() meta = self.serializer.context.build(ProductType) var = meta.find_var("size") with self.assertRaises(SerializerError) as cm: self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertEqual("ColorType is not derived from SizeType", str(cm.exception)) @mock.patch.object(XmlContext, "is_derived", return_value=True) def test_set_xsi_type_when_value_is_derived_from_var_clazz(self, *args): elem = Element("foo") value = Items() meta = self.serializer.context.build(ProductType) items_meta = self.serializer.context.build(Items) var = meta.find_var("size") self.serializer.set_xsi_type(elem, value, var, self.namespaces) self.assertEqual(items_meta.source_qname, elem.attrib[QNames.XSI_TYPE]) def test_next_value(self): @dataclass class A: x0: Optional[int] = field(default=None) x1: List[int] = field( default_factory=list, metadata=dict(type="Element", sequential=True) ) x2: List[int] = field( default_factory=list, metadata=dict(type="Element", sequential=True) ) x3: Optional[int] = field(default=None) obj = A(x0=1, x1=[2, 3, 4], x2=[6, 7], x3=8) meta = self.serializer.context.build(A) x0 = meta.find_var("x0") x1 = meta.find_var("x1") x2 = meta.find_var("x2") x3 = meta.find_var("x3") actual = self.serializer.next_value(meta, obj) expected = [ (x0, 1), (x1, 2), (x2, 6), (x1, 3), (x2, 7), (x1, 4), (x3, 8), ] self.assertIsInstance(actual, Iterator) self.assertEqual(expected, list(actual))
class XmlSerializerTests(TestCase): def setUp(self) -> None: self.serializer = XmlSerializer() def test_write_object_with_derived_element(self): book = BookForm(id="123") obj = DerivedElement(qname="item", value=book) result = self.serializer.write_object(obj) expected = [ (XmlWriterEvent.START, "item"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, "{urn:books}BookForm"), (XmlWriterEvent.END, "item"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_dataclass(self): book = BookForm(id="123", title="Misterioso: A Crime Novel", price=19.5) result = self.serializer.write_object(book) expected = [ (XmlWriterEvent.START, "BookForm"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.START, "title"), (XmlWriterEvent.DATA, "Misterioso: A Crime Novel"), (XmlWriterEvent.END, "title"), (XmlWriterEvent.START, "price"), (XmlWriterEvent.DATA, "19.5"), (XmlWriterEvent.END, "price"), (XmlWriterEvent.END, "BookForm"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_dataclass_can_overwrite_params(self): book = BookForm(id="123", title="Misterioso: A Crime Novel", price=19.5) result = self.serializer.write_dataclass(book, "xsdata", "book", True, "foo:book") expected = [ (XmlWriterEvent.START, "book"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, "foo:book"), (XmlWriterEvent.ATTR, QNames.XSI_NIL, "true"), (XmlWriterEvent.START, "title"), (XmlWriterEvent.DATA, "Misterioso: A Crime Novel"), (XmlWriterEvent.END, "title"), (XmlWriterEvent.START, "price"), (XmlWriterEvent.DATA, "19.5"), (XmlWriterEvent.END, "price"), (XmlWriterEvent.END, "book"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_dataclass_with_no_dataclass(self): with self.assertRaises(XmlContextError) as cm: next(self.serializer.write_dataclass(1)) self.assertEqual("Object <class 'int'> is not a dataclass.", str(cm.exception)) def test_write_mixed_content(self): var = XmlVar(wildcard=True, qname="a", name="a", mixed=True) book = BookForm(id="123") ebook = DerivedElement("ebook", BookForm(id="123")) value = ["text", AnyElement(qname="br"), book, ebook, "tail"] result = self.serializer.write_value(value, var, "xsdata") expected = [ (XmlWriterEvent.DATA, "text"), (XmlWriterEvent.START, "br"), (XmlWriterEvent.DATA, None), (XmlWriterEvent.END, "br"), (XmlWriterEvent.START, "{xsdata}BookForm"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.END, "{xsdata}BookForm"), (XmlWriterEvent.START, "ebook"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.END, "ebook"), (XmlWriterEvent.DATA, "tail"), ] self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_data(self): var = XmlVar(text=True, qname="a", name="a") expected = [(XmlWriterEvent.DATA, "123")] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_tokens(self): var = XmlVar(element=True, qname="a", name="a", tokens=True) result = self.serializer.write_value([], var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(0, len(list(result))) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ["1", QName("{a}b"), "3"]), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value([1, QName("{a}b"), 3], var, "xsdata") self.assertEqual(expected, list(result)) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ["1", "2", "3"]), (XmlWriterEvent.END, "a"), (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ["4", "5", "6"]), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value([[1, 2, 3], [4, 5, 6]], var, "xsdata") self.assertEqual(expected, list(result)) var = XmlVar(element=True, qname="a", name="a", tokens=True, nillable=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_NIL, "true"), (XmlWriterEvent.DATA, []), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value([], var, "xsdata") self.assertEqual(expected, list(result)) def test_write_any_type_with_primitive(self): var = XmlVar(wildcard=True, qname="a", name="a") expected = [(XmlWriterEvent.DATA, "str")] result = self.serializer.write_value("str", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_primitive_element(self): var = XmlVar(element=True, qname="a", name="a", types=[object]) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "str"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("str", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_any_element(self): var = XmlVar(wildcard=True, qname="a", name="a") value = AnyElement( qname="a", text="b", tail="c", attributes={ "d": 1, "e": 2 }, children=[AnyElement(text="g"), "h"], ) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "d", 1), (XmlWriterEvent.ATTR, "e", 2), (XmlWriterEvent.DATA, "b"), (XmlWriterEvent.DATA, "g"), (XmlWriterEvent.DATA, "h"), (XmlWriterEvent.END, "a"), (XmlWriterEvent.DATA, "c"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_derived_element_primitive(self): var = XmlVar(wildcard=True, qname="a", name="a") value = DerivedElement(qname="a", value=1) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName(str(DataType.SHORT))), (XmlWriterEvent.DATA, 1), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_any_type_with_derived_element_dataclass(self): var = XmlVar(wildcard=True, qname="a", name="a") value = DerivedElement(qname="a", value=BookForm(title="def"), substituted=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName("{urn:books}BookForm")), (XmlWriterEvent.START, "title"), (XmlWriterEvent.DATA, "def"), (XmlWriterEvent.END, "title"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_xsi_type(self): var = XmlVar(element=True, qname="a", name="a", dataclass=True, types=[BookForm]) value = BookForm(id="123") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_xsi_type_with_derived_class(self): var = XmlVar(element=True, qname="a", name="a", dataclass=True, types=[BookForm]) ebook = make_dataclass("eBook", [], bases=(BookForm, )) value = ebook(id="123") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "id", "123"), (XmlWriterEvent.ATTR, "lang", "en"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName("eBook")), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_xsi_type_with_illegal_derived_class(self): var = XmlVar(element=True, qname="a", name="a", dataclass=True, types=[BookForm]) ebook = make_dataclass("eBook", []) value = ebook() result = self.serializer.write_value(value, var, "xsdata") with self.assertRaises(SerializerError) as cm: list(result) self.assertEqual("eBook is not derived from BookForm", str(cm.exception)) def test_write_element(self): var = XmlVar(element=True, qname="a", name="a") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_element_with_nillable_true(self): var = XmlVar(element=True, qname="a", name="a", nillable=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_NIL, "true"), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_element_with_any_type_var(self): var = XmlVar(element=True, qname="a", name="a", types=[object], any_type=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, QNames.XSI_TYPE, QName(str(DataType.SHORT))), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(123, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_element_with_any_type_var_ignore_xs_string(self): var = XmlVar(element=True, qname="a", name="a", types=[object], any_type=True) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, ""), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "123"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value("123", var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_derived_primitive_value(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[int])], ) value = DerivedElement(qname="a", value=1) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "1"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_derived_dataclass(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[A])], ) value = DerivedElement(qname="a", value=A("foo")) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.ATTR, "a0", "foo"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_generic_object(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[int])], ) value = AnyElement(qname="a", text="1") expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "1"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_with_raw_value(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[ XmlVar(element=True, qname="a", name="a", types=[int]), XmlVar(element=True, qname="b", name="b", types=[int], tokens=True), ], ) expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "1"), (XmlWriterEvent.END, "a"), (XmlWriterEvent.START, "b"), (XmlWriterEvent.DATA, ["1", "2"]), (XmlWriterEvent.END, "b"), ] result = self.serializer.write_value([1, [1, 2]], var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_write_choice_when_no_matching_choice_exists(self): var = XmlVar( elements=True, name="compound", qname="compound", choices=[XmlVar(element=True, qname="a", name="a", types=[float])], ) with self.assertRaises(SerializerError) as cm: result = self.serializer.write_value(1, var, "xsdata") next(result) msg = "XmlElements undefined choice: `compound` for `<class 'int'>`" self.assertEqual(msg, str(cm.exception)) def test_write_value_with_list_value(self): var = XmlVar(element=True, qname="a", name="a", list_element=True) value = [True, False] expected = [ (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "true"), (XmlWriterEvent.END, "a"), (XmlWriterEvent.START, "a"), (XmlWriterEvent.DATA, "false"), (XmlWriterEvent.END, "a"), ] result = self.serializer.write_value(value, var, "xsdata") self.assertIsInstance(result, Generator) self.assertEqual(expected, list(result)) def test_next_value(self): obj = A(x0=1, x1=[2, 3, 4], x2=[6, 7], x3=[9]) meta = self.serializer.context.build(A) x0 = meta.find_var("x0") x1 = meta.find_var("x1") x2 = meta.find_var("x2") x3 = meta.find_var("x3") actual = self.serializer.next_value(obj, meta) expected = [ (x0, 1), (x1, 2), (x2, 6), (x3, 9), (x1, 3), (x2, 7), (x1, 4), ] self.assertIsInstance(actual, Generator) self.assertEqual(expected, list(actual)) def test_next_attribute(self): obj = A(a0="foo", a1={"b": "c", "d": "e"}) meta = self.serializer.context.build(A) actual = self.serializer.next_attribute(obj, meta, False, None) expected = [ ("a0", "foo"), ("b", "c"), ("d", "e"), ] self.assertIsInstance(actual, Generator) self.assertEqual(expected, list(actual)) actual = self.serializer.next_attribute(obj, meta, True, "xs:bool") expected.extend([ (QNames.XSI_TYPE, "xs:bool"), (QNames.XSI_NIL, "true"), ]) self.assertEqual(expected, list(actual)) def test_render_mixed_content(self): @dataclass class Span: class Meta: name = "span" content: str @dataclass class Example: class Meta: name = "p" content: List[object] = field( default_factory=list, metadata=dict( type="Wildcard", namespace="##any", mixed=True, min_occurs=0, max_occurs=9223372036854775807, ), ) obj = Example() obj.content.append(AnyElement(qname="b", text="Mr.")) obj.content.append(Span("chris")) obj.content.append("!") self.serializer.pretty_print = False result = self.serializer.render(obj).splitlines() self.assertEqual("<p><b>Mr.</b><span>chris</span>!</p>", result[1]) obj = Example() obj.content.append("Hi ") obj.content.append(AnyElement(qname="b", text="Mr.")) obj.content.append(Span("chris")) obj.content.append("!") result = self.serializer.render(obj).splitlines() self.assertEqual("<p>Hi <b>Mr.</b><span>chris</span>!</p>", result[1])
class Application(SIPApplication): def __init__(self, *, config: Configuration) -> None: self.config = config self.serializer = XmlSerializer(config=SerializerConfig( pretty_print=False)) self.parser = XmlParser(context=XmlContext()) self.requests: WeakValueDictionary[str, Future] = WeakValueDictionary({}) super().__init__() def start(self): notification_center = NotificationCenter() notification_center.add_observer(self, name='SIPEngineGotMessage') notification_center.add_observer(self, name='SIPMessageDidSucceed') notification_center.add_observer(self, name='SIPMessageDidFail') notification_center.add_observer(self, name='SIPApplicationDidStart') super().start(MemoryStorage()) async def send_request(self, arc_name: str, scaip_request: ScaipRequest): logger.info(f"send_request to {arc_name}: {scaip_request}") config = self.config arc_config = config.get_arc_config(arc_name) if not arc_config: raise ValueError(f"no configuration found for ARC {arc_name}") xml_model = scaip_request.to_xml_model() xml_str = self.serializer.render(xml_model) result = self.new_result_future(scaip_request.reference) if scaip_request.caller_id.startswith( "sip") and scaip_request.caller_id != "sip:": caller_id = URI(scaip_request.caller_id) sender = SIPURI(user=caller_id.user, host=caller_id.host, port=caller_id.port) else: sender = self.get_user_agent_uri() receiver = SIPURI(user=arc_config.username, host=arc_config.hostname, port=arc_config.port) message = Message(FromHeader(sender), ToHeader(receiver), RouteHeader(receiver), 'application/scaip+xml', xml_str) message.send() logger.info(f"sent message: {xml_str}") scaip_response = await result logger.info(f"received response: {scaip_response}") return scaip_response def new_result_future(self, reference: str) -> Future: loop = asyncio.get_running_loop() result = loop.create_future() self.requests[reference] = result return result def get_user_agent_uri(self) -> SIPURI: sip_config = self.config.sip return SIPURI(user=sip_config.username, host=sip_config.hostname, port=sip_config.port) def _NH_SIPApplicationDidStart(self, notification): logger.info("SIPApplicationDidStart") def _NH_SIPMessageDidSucceed(self, notification): logger.info("SIPMessageDidSucceed") def _NH_SIPMessageDidFail(self, notification): logger.info("SIPMessageDidFail") message = notification.sender xml_model = self.parser.from_bytes(message.body, Mrq) result = self.requests.get(xml_model.ref, None) if result: # TODO: return proper error result.set_exception( HTTPException(status_code=500, detail="SIPMessageDidFail")) def _NH_SIPEngineGotMessage(self, notification): logger.info("SIPEngineGotMessage") logger.info(f"got XML: {notification.data.body}") xml_model = self.parser.from_bytes(notification.data.body, Mrs) scaip_response = ScaipResponse.from_xml_model(xml_model) result = self.requests.get(xml_model.ref, None) if result: result.set_result(scaip_response)
def ToXML(header: ismrmrdHeader, encoding='ascii'): config = SerializerConfig(encoding=encoding, pretty_print=True) serializer = XmlSerializer(config) return serializer.render(header)
from generated.test import Shiporder from xsdata.formats.dataclass.serializers.config import SerializerConfig from xsdata.formats.dataclass.serializers import XmlSerializer import xmlschema config = SerializerConfig(pretty_print=True) xml_serializer = XmlSerializer(config=config) schema = xmlschema.XMLSchema('test.xsd') order = Shiporder() #order.name = "test" xml = xml_serializer.render(order) print(xml) schema.validate(xml)