XML序列化是什么 如何将对象转换为XML字符串

8次阅读

xml序列化是将对象结构按类型、字段名和嵌套关系生成带层级与命名空间的XML字符串,核心在于保留结构语义;java用JAXB(JDK9+需手动引入jakarta.xml.bind依赖),python常用xml.etree.ElementTree手动构建,.net用XmlSerializer默认忽略NULL字段和只读属性。

XML序列化是什么 如何将对象转换为XML字符串

XML序列化就是把对象结构转成符合XML语法的字符串

它不是简单拼接标签,而是按类型、字段名、嵌套关系生成带层级和命名空间的XML。核心是保留对象的结构语义,而非仅输出文本。Java里用 JAXBContext,.NET用 XmlSerializer,Python常用 xml.etree.ElementTree 或第三方库如 dicttoxml

Java中用JAXB将对象转XML字符串(Java 8+需注意模块问题)

默认JDK 8自带JAXB,但JDK 9+已移除,必须显式添加依赖。否则运行时抛 ClassNotFoundException: javax.xml.bind.JAXBContext

  • 添加maven依赖:
       jakarta.xml.bind   jakarta.xml.bind-api   4.0.0     org.glassfish.jaxb   jaxb-runtime   4.0.3 
  • 对象类必须有无参构造函数,字段或getter需加 @XmlElement(可选),根元素用 @XmlRootElement
  • 序列化代码:
    Person person = new Person("Alice", 30); JAXBContext context = JAXBContext.newinstance(Person.class); Marshaller marshaller = context.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); StringWriter writer = new StringWriter(); marshaller.marshal(person, writer); String xml = writer.toString();

Python用xml.etree.ElementTree手动构建更可控

标准库不支持直接序列化任意对象,但适合结构明确、字段少的场景。比第三方库轻量,无额外依赖,且能精确控制命名空间、属性顺序、CDATA等细节。

  • 不推荐用 dicttoxml 处理含嵌套列表或自定义类型的数据——它会把所有值转成字符串,丢失原始类型信息
  • 手动构建示例:
    import xml.etree.ElementTree as ET 

    def person_to_xml(person): root = ET.Element("person") name_el = ET.SubElement(root, "name") name_el.text = person.name age_el = ET.SubElement(root, "age") age_el.text = str(person.age) return ET.tostring(root, encoding="unicode")

    xml_str = person_to_xml(Person("Bob", 25))

  • 注意:ET.tostring() 默认不带XML声明,如需 ,得自己拼接或用 xml.dom.minidom 格式化

.NET中XmlSerializer默认不序列化null字段和只读属性

这是最容易被忽略的行为差异。比如一个 public string Nickname { get; set; } = null; 字段,在序列化结果里直接消失,而不是输出空标签或空值。

  • 要强制输出空元素,给属性加 [XmlElement(IsNullable = true)],且字段类型必须是可空引用类型(C# 8+启用nullable后需写 string?
  • 只读属性(只有getter)默认跳过,即使加了 [XmlElement] 也无效;必须提供setter,哪怕设为private
  • 序列化时若对象含循环引用(如父子双向引用),会直接抛 InvalidOperationException,无法自动处理,需提前解耦或改用DataContractSerializer

实际项目里,XML序列化最常卡在命名空间不一致、日期格式不兼容、特殊字符未转义这三处。尤其当对接老系统时,别假设对方接受标准ISO格式——先抓包看它真正要的是 2024-05-20 还是 20240520

text=ZqhQzanResources