Skip to content

Unintended namespace overwriting across independent models #288

@Visparu

Description

@Visparu

Hi there,

first off, thanks a ton for this module. It has drastically helped me keep my XML-related code in line with all my other Pydantic models.

I have come across an unusual and, from what I can tell, probably unintended behavior. When assigning multiple namespace maps with different names but the same ns-links and independently assigning them to different models, the last assigned namespace map overwrites all previously used ones. Instead of trying to explain it further, I'll just provide an example:

I created the following file:

from pydantic_xml import BaseXmlModel, element


_SOAP_NS: str = "https://www.w3.org/2003/05/soap-envelope"
_SAP_NS:  str = "urn:sap-com:document:sap:soap:functions:mc-style"

_REQUEST_NSMAP:  dict[str, str] = {"soap": _SOAP_NS, "urn": _SAP_NS}
_RESPONSE_NSMAP: dict[str, str] = {"env":  _SOAP_NS, "n0":  _SAP_NS}


class Test(BaseXmlModel):
    test1: int = element("Test1")
    test2: str = element("Test2")


##### Request models #####

class RequestBody(BaseXmlModel, ns = "urn", nsmap = _REQUEST_NSMAP, tag = "Body"):
    test: Test = element("Test", "urn")


class RequestEnvelope(BaseXmlModel, ns = "soap", nsmap = _REQUEST_NSMAP, tag = "Envelope"):
    body: RequestBody = element("Body", "soap")


##### Response models #####

class ResponseBody(BaseXmlModel, ns = "n0", nsmap = _RESPONSE_NSMAP, tag = "Body"):
    test: Test = element("Test", "n0")


class ResponseEnvelope(BaseXmlModel, ns = "env", nsmap = _RESPONSE_NSMAP, tag = "Envelope"):
    body: ResponseBody = element("Body", "env")


##### Execution #####

request_envelope: RequestEnvelope = RequestEnvelope(
    body=RequestBody(
        test=Test(
            test1=1,
            test2="abc"
        )
    )
)

response_envelope: ResponseEnvelope = ResponseEnvelope(
    body=ResponseBody(
        test=Test(
            test1=2,
            test2="def"
        )
    )
)

print("===============REQUEST================")
print(request_envelope.to_xml())
print("===============RESPONSE================")
print(response_envelope.to_xml())

As you can see, I create two sets of SOAP envelopes - RequestEnvelope and ResponseEnvelope. These envelopes should be namespaced differently, specifically:

  • RequestEnvelope and RequestBody should be in namespace soap and Test1 should be in namespace urn
  • ResponseEnvelope and ResponseBody should be in namespace env and Test1 should be in namespace n0

So the expected output would be:

RequestEnvelope

<soap:Envelope xmlns:soap="https://www.w3.org/2003/05/soap-envelope" xmlns:urn="urn:sap-com:document:sap:soap:functions:mc-style">
	<soap:Body>
		<urn:Test>
			<Test1>1</Test1>
			<Test2>abc</Test2>
		</urn:Test>
	</soap:Body>
</soap:Envelope>

ResponseEnvelope

<env:Envelope xmlns:env="https://www.w3.org/2003/05/soap-envelope" xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
	<env:Body>
		<n0:Test>
			<Test1>2</Test1>
			<Test2>def</Test2>
		</n0:Test>
	</env:Body>
</env:Envelope>

However, what actually happens is that the RequestEnvelope also uses env and n0:

RequestEnvelope

<env:Envelope xmlns:env="https://www.w3.org/2003/05/soap-envelope" xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
	<env:Body>
		<n0:Test>
			<Test1>1</Test1>
			<Test2>abc</Test2>
		</n0:Test>
	</env:Body>
</env:Envelope>

ResponseEnvelope

<env:Envelope xmlns:env="https://www.w3.org/2003/05/soap-envelope" xmlns:n0="urn:sap-com:document:sap:soap:functions:mc-style">
	<env:Body>
		<n0:Test>
			<Test1>2</Test1>
			<Test2>def</Test2>
		</n0:Test>
	</env:Body>
</env:Envelope>

This issue is very likely connected to the namespaces pointing to the same URLs. When given different URLs, the given example works just as intended. I have not found any workaround for this and it haunts me quite a bit since I do have use cases for which this scenario applies.

I would greatly appreciate any help here. I would already be very happy with any workaround for the time being.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions