-
-
Notifications
You must be signed in to change notification settings - Fork 79
Insert an XML string as a (raw) element #1143
-
I have generated the data classes. At one point the schema allows arbitrary XML, I'm generating the XML string to be contained in this element with a different library. How can I inject this raw XML string into the dataclass element tree? If I just pass it as plain string into the constructor, it is serialized to the document but as escaped string, i.e.:
<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" > <rdf:Description rdf:about="urn:id:record1"> <dc:title>Record 1</dc:title> </rdf:Description> </rdf:RDF>
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 3 comments 1 reply
-
I think my question has some part in common with #842, but the other way around.
Beta Was this translation helpful? Give feedback.
All reactions
-
As a workaround for my problem I have now the following code, that parses the XML payload, that I get and injects it into the object tree so that it can be returned. But this is not very nice.
from dataclasses import dataclass, field from typing import Optional from xsdata.formats.dataclass.parsers import XmlParser from xsdata.formats.dataclass.serializers import XmlSerializer @dataclass class WrapperType: """The Type to hold any RDF data""" class Meta: name = "wrapper" other_element: Optional[object] = field( metadata={ "type": "Wildcard", "namespace": "##any", }, ) @dataclass class RecordType: class Meta: name = "Record" header: str = field(default="Some info", metadata={"type": "Attribute"}) wrapper: Optional[WrapperType] = field( default=None, metadata={ "type": "Element", }, ) rdf_string = """<?xml version="1.0" encoding="utf-8"?> <rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <rdf:Description rdf:about="urn:id:record2"><dc:title>Record 2</dc:title></rdf:Description> <rdf:Description rdf:about="urn:id:record3"><dc:title>Record 3</dc:title></rdf:Description> </rdf:RDF> """ rdf_data = rdf_string.splitlines() metadata_string = f"""{rdf_data[0]} <wrapper> {"\n".join(rdf_data[1:])} </wrapper> """ model = RecordType( header="Here comes the data", wrapper=XmlParser().from_string(metadata_string, WrapperType), ) output = XmlSerializer().render(model) print(output)
The output is:
<?xml version="1.0" encoding="UTF-8"?>
<Record header="Here comes the data"><wrapper><ns0:RDF xmlns:ns0="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><ns0:Description ns0:about="urn:id:record2"><ns1:title xmlns:ns1="http://purl.org/dc/elements/1.1/">Record 2</ns1:title></ns0:Description><ns0:Description ns0:about="urn:id:record3"><ns1:title xmlns:ns1="http://purl.org/dc/elements/1.1/">Record 3</ns1:title></ns0:Description></ns0:RDF></wrapper></Record>
but the namespaces are replaced by ns0 ... which is not nice, but works.
I have also experimented with a custom Converter, that returned the data with the serialize method, but this string was then escaped down the road again.
Beta Was this translation helpful? Give feedback.
All reactions
-
but the namespaces are replaced by ns0 ... which is not nice, but works.
You should probably specify the namespace :
output = XmlSerializer().render(model,nsmap={'dc':'http://purl.org/dc/elements/1.1/','rdc':'http://www.w3.org/1999/02/22-rdf-syntax-ns#'})
See:https://xsdata.readthedocs.io/en/latest/data_binding/xml_serializing/ (Custom namespace prefixes,Default namespace)
Same when you read your xml payload, you need to capture the namespace:
nsmap = dict()
model = RecordType(
header="Here comes the data",
wrapper=XmlParser().from_string(metadata_string, WrapperType,ns_map=nsmap),
)
So you can rewrite them back properly. See: https://xsdata.readthedocs.io/en/latest/data_binding/xml_parsing/ (Capture namespace prefixes)
Beta Was this translation helpful? Give feedback.
All reactions
-
To demonstrate the use case from a different perspective I have opened: #1161
Beta Was this translation helpful? Give feedback.