You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Python中构建的类实例转换为层级清晰的XML结构?

Python类实例转结构化XML方案

手动构建XML(最灵活可控)

直接用Python内置的xml.etree.ElementTree模块,递归遍历类实例属性,手动构建XML层级结构,标签和内容完全自定义。

步骤示例:

  1. 定义业务类(已填充随机数据)
import xml.etree.ElementTree as ET
import random
from datetime import datetime

class Customer:
    def __init__(self):
        self.id = random.randint(1000, 9999)
        self.name = f"Customer_{random.randint(1, 100)}"
        self.email = f"user{random.randint(1, 100)}@example.com"

class Item:
    def __init__(self):
        self.sku = f"SKU_{random.randint(100, 999)}"
        self.quantity = random.randint(1, 5)
        self.price = round(random.uniform(10.0, 100.0), 2)

class Order:
    def __init__(self):
        self.order_id = f"ORD_{random.randint(10000, 99999)}"
        self.order_date = datetime.now().strftime("%Y-%m-%d")
        self.customer = Customer()
        self.items = [Item() for _ in range(random.randint(1, 3))]
  1. 递归转换函数:类实例转XML元素
def instance_to_xml(instance, parent=None):
    # 用类名作为XML标签,也可自定义为小写或别名
    tag = instance.__class__.__name__
    element = ET.Element(tag) if parent is None else ET.SubElement(parent, tag)
    
    for attr_name, attr_value in instance.__dict__.items():
        # 基础类型直接生成子元素
        if isinstance(attr_value, (str, int, float, bool)):
            child = ET.SubElement(element, attr_name)
            child.text = str(attr_value)
        # 列表类型生成父容器,再递归处理每个元素
        elif isinstance(attr_value, list):
            list_container = ET.SubElement(element, attr_name)
            for item in attr_value:
                instance_to_xml(item, list_container)
        # 自定义类实例,递归嵌套处理
        elif hasattr(attr_value, '__dict__'):
            instance_to_xml(attr_value, element)
    
    return element
  1. 生成并美化XML
# 创建顶层实例
order = Order()

# 转换为XML根元素
root = instance_to_xml(order)

# 美化XML格式(ElementTree默认无缩进,手动添加)
def indent(elem, level=0):
    i = "\n" + level*"  "
    if len(elem):
        if not elem.text or not elem.text.strip():
            elem.text = i + "  "
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
        for elem in elem:
            indent(elem, level+1)
        if not elem.tail or not elem.tail.strip():
            elem.tail = i
    else:
        if level and (not elem.tail or not elem.tail.strip()):
            elem.tail = i

indent(root)

# 输出XML字符串
xml_str = ET.tostring(root, encoding='utf-8', method='xml').decode('utf-8')
print(xml_str)

# 保存到文件
ET.ElementTree(root).write('output.xml', encoding='utf-8', xml_declaration=True)

基于Dataclass的序列化

如果用dataclasses定义类,代码更简洁规范,且可直接复用上面的转换逻辑(dataclass实例可通过__dict__访问属性):

from dataclasses import dataclass, field

@dataclass
class Customer:
    id: int = field(default_factory=lambda: random.randint(1000, 9999))
    name: str = field(default_factory=lambda: f"Customer_{random.randint(1, 100)}")
    email: str = field(default_factory=lambda: f"user{random.randint(1, 100)}@example.com")

@dataclass
class Item:
    sku: str = field(default_factory=lambda: f"SKU_{random.randint(100, 999)}")
    quantity: int = field(default_factory=lambda: random.randint(1, 5))
    price: float = field(default_factory=lambda: round(random.uniform(10.0, 100.0), 2))

@dataclass
class Order:
    order_id: str = field(default_factory=lambda: f"ORD_{random.randint(10000, 99999)}")
    order_date: str = field(default_factory=lambda: datetime.now().strftime("%Y-%m-%d"))
    customer: Customer = field(default_factory=Customer)
    items: list[Item] = field(default_factory=lambda: [Item() for _ in range(random.randint(1, 3))])

# 直接复用instance_to_xml和indent函数

第三方库简化流程(可选)

不想写递归逻辑的话,可用dicttoxml库,先把类实例转成字典,再转XML:

from dicttoxml import dicttoxml
import xml.dom.minidom

# 类实例转字典
def instance_to_dict(instance):
    if isinstance(instance, list):
        return [instance_to_dict(item) for item in instance]
    if hasattr(instance, '__dict__'):
        return {k: instance_to_dict(v) for k, v in instance.__dict__.items()}
    return instance

# 转换并美化
order = Order()
order_dict = instance_to_dict(order)
xml_str = dicttoxml(order_dict, root_name='Order', attr_type=False)
pretty_xml = xml.dom.minidom.parseString(xml_str).toprettyxml()
print(pretty_xml)

关于pickle的说明

pickle是Python专用的对象序列化工具,输出二进制格式,仅用于Python环境内的对象持久化/传输,完全无法生成标准可读XML,不适合你的需求。

内容的提问来源于stack exchange,提问作者kompressor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:47:19