Asy*_*llz 6 python xml pydantic
我正在开发一个使用大量 xml 的项目,并且想使用 pydantic 来建模对象。在本例中,我简化了 xml,但包含了一个示例对象。
<ns:SomeType name="NameType" shortDescription="some data">
<ns:Bar
thingOne="alpha"
thingTwo="beta"
thingThree="foobar"/>
</ns:SomeType>
Run Code Online (Sandbox Code Playgroud)
代码
from pydantic import BaseModel
from typing import Optional, List
from xml.etree import ElementTree as ET
class Bar(BaseModel):
thing_one: str
thing_two: str
thing_three: str
class SomeType(BaseModel):
name: str
short_description: str
bar: Optional[Bar]
def main():
with open("path/to/file.xml") as fp:
source = fp.read()
root = ET.fromstring(source)
some_type_list = []
for child in root:
st = SomeType(
name=child.attrib["name"],
short_description=child.attrib["shortDescription"],
)
for sub in child:
st.bar = Bar(
thing_one=sub.attrib["thingOne"],
thing_two=sub.attrib["thingTwo"],
thing_three=sub.attrib["thingThree"],
)
Run Code Online (Sandbox Code Playgroud)
我研究了 BaseModel.parse_obj 或 BaseModel.parse_raw 但我认为这不能解决问题。我还认为我可以尝试使用 xmltodict 来转换 xml,命名空间和 @ 属性会更加妨碍......
>>> import xmltodict
>>> xmltodict.parse(input_xml)
{'ns:SomeType': {'@name': 'NameType', '@shortDescription': 'some data', ... }}
Run Code Online (Sandbox Code Playgroud)
xmltodict如果将其与字段别名结合起来,可以在您的示例中提供帮助:
from typing import Optional
import xmltodict
from pydantic import BaseModel, Field
class Bar(BaseModel):
thing_one: str = Field(alias="@thingOne")
thing_two: str = Field(alias="@thingTwo")
thing_three: str = Field(alias="@thingThree")
class SomeType(BaseModel):
name: str = Field(alias="@name")
short_description: str = Field(alias="@shortDescription")
bar: Optional[Bar] = Field(alias="ns:Bar")
class Root(BaseModel):
some_type: SomeType = Field(alias="ns:SomeType")
print(
Root.model_validate(
xmltodict.parse(
"""<ns:SomeType name="NameType" shortDescription="some data">
<ns:Bar
thingOne="alpha"
thingTwo="beta"
thingThree="foobar"/>
</ns:SomeType>""")).some_type)
Run Code Online (Sandbox Code Playgroud)
输出:
name='NameType' short_description='some data' bar=Bar(thing_one='alpha', thing_two='beta', thing_three='foobar')
Run Code Online (Sandbox Code Playgroud)
您可以在上面的示例中看到,Root需要一个模型,因为字典有一个ns:SomeType键。
| 归档时间: |
|
| 查看次数: |
5263 次 |
| 最近记录: |