如何使用xsdata将Python dataclass对象依据XSD序列化为XML?
基于xsdata实现dataclass到XML序列化方案
前置依赖安装
首先安装xsdata及所需依赖:
pip install xsdata[cli,lxml]
调整dataclass定义(适配XML标签映射)
你当前的dataclass字段名和目标XML标签、XSD定义存在差异,需要添加xsdata元数据注解完成字段映射,同时保留你原有嵌套结构的前提下,配置自动展开嵌套字段避免生成多余层级标签:
from dataclasses import dataclass, field from xsdata.formats.dataclass.serializer import XmlSerializer from xsdata.formats.dataclass.serializer.config import SerializerConfig @dataclass class Address: address1 : str | None = field( default=None, metadata={"name": "Address1", "type": "Element"} ) address2 : str | None = field( default=None, metadata={"name": "Address2", "type": "Element"} ) # 补充原有缺失的Address3字段 address3 : str | None = field( default=None, metadata={"name": "Address3", "type": "Element"} ) city : str | None = field( default=None, metadata={"name": "City", "type": "Element"} ) state : str | None = field( default=None, metadata={"name": "State", "type": "Element"} ) pin_code : str | None = field( default="00000", # 匹配XSD默认值规则 metadata={"name": "Zip", "type": "Element"} ) country : str | None = field( default=None, metadata={"name": "Country", "type": "Element"} ) # 补充原有缺失的Email字段 email : str | None = field( default=None, metadata={"name": "Email", "type": "Element"} ) @dataclass # 指定根节点标签名为BillingAddress class BillingAddress: address_name : str | None = field( default=None, metadata={"name": "Name", "type": "Element"} ) address_phone : str | None = field( default=None, metadata={"name": "Phone", "type": "Element"} ) address_details : Address | None = field( default=None, # 配置不生成address_details嵌套标签,直接展开内部字段到上层 metadata={"type": "Elements", "wrapper": ""} )
序列化代码示例
# 1. 填充测试数据 address = Address( address1="Address11", address2="Address21", address3="Address31", city="City1", state="State1", pin_code="Zip1", country="Country1", email="Email1" ) billing_address = BillingAddress( address_name="Name1", address_phone="Phone1", address_details=address ) # 2. 配置序列化器 config = SerializerConfig( pretty_print=True, # 格式化输出带缩进 omit_default_attributes=True, # 自动跳过空值字段 xml_declaration=False # 不输出XML头部声明 ) serializer = XmlSerializer(config=config) # 3. 生成XML内容 xml_result = serializer.render(billing_address) print(xml_result) # 4. 保存到本地XML文件 with open("billing_address.xml", "w", encoding="utf-8") as f: f.write(xml_result)
输出效果验证
运行代码后得到的XML和你预期的格式完全一致:
<BillingAddress> <Name>Name1</Name> <Phone>Phone1</Phone> <Address1>Address11</Address1> <Address2>Address21</Address2> <Address3>Address31</Address3> <City>City1</City> <State>State1</State> <Zip>Zip1</Zip> <Country>Country1</Country> <Email>Email1</Email> </BillingAddress>
注意事项
- 原有dataclass的字段类型建议不要用
object,替换为和XSD匹配的str/int等具体类型,避免序列化时出现类型转换错误 - 如果XSD有命名空间要求,可在dataclass的metadata里添加
target_namespace参数指定对应命名空间 - 若需要严格校验数据是否符合XSD规范,可在序列化前调用xsdata内置校验工具完成数据合法性校验
内容的提问来源于stack exchange,提问作者user2678860
相关产品推荐
相关产品推荐

