-
-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convert xmltodict result to structured data #421
Comments
Hello, you're on the right track! I've modified your example to this: # example.py
from __future__ import annotations
from typing import Any
from attrs import define
from cattr.gen import make_dict_structure_fn, override
from cattr.preconf.json import make_converter
@define
class Ns2LogTransaction:
_xmlns_ns2: str
"""@xmlns:ns2"""
@define
class SBody:
ns2_logTransaction: Ns2LogTransaction
"""ns2:logTransaction"""
@define
class SEnvelope:
_xmlns_S: str
"""@xmlns:S"""
S_Body: SBody
"""S:Body"""
@define
class LogTransactionRequest:
S_Envelope: SEnvelope
"""S:Envelope"""
@classmethod
def from_dict(cls, data: dict[str, Any]):
"""
https://github.com/python-attrs/attrs/issues/417
"""
converter = make_converter()
converter.register_structure_hook(
Ns2LogTransaction,
make_dict_structure_fn(
Ns2LogTransaction, converter, _xmlns_ns2=override(rename="@xmlns:ns2")
),
)
converter.register_structure_hook(
SBody,
make_dict_structure_fn(
SBody,
converter,
ns2_logTransaction=override(rename="ns2:logTransaction"),
),
)
converter.register_structure_hook(
SEnvelope,
make_dict_structure_fn(
SEnvelope,
converter,
_xmlns_S=override(rename="@xmlns:S"),
S_Body=override(rename="S:Body"),
),
)
converter.register_structure_hook(
LogTransactionRequest,
make_dict_structure_fn(
LogTransactionRequest,
converter,
S_Envelope=override(rename="S:Envelope"),
),
)
return converter.structure(data, cls)
if __name__ == "__main__":
d = {
"S:Envelope": {
"@xmlns:S": "http://schemas.xmlsoap.org/soap/envelope/",
"S:Body": {"ns2:logTransaction": {"@xmlns:ns2": "http://random.url/1"}},
}
}
lt = LogTransactionRequest.from_dict(d)
print(lt) Notable changes:
One other thing: you shouldn't create a converter in the Cattrs basically generates and compiles functions for un/structuring; this is why the order in which hooks are registered is important and why you want do avoid recreating converters. Let me know if you have any other questions! |
Thank you! this is great! Will heed your advice! |
Description
Hi, I have XML files which I want to read and import into structured objects using
attrs
andcattrs
. For xml reading, I'm usingxmltodict
, with the returned dictionary often having keys containing special characters like:
or@
. I've perused this issue python-attrs/attrs#417 and came up with the solution below but I'm getting an error which I don't understand.What I Did
script:
Traceback:
The text was updated successfully, but these errors were encountered: