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

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等细节。
本文档主要讲述的是JSON.NET 简单的使用;JSON.NET使用来将.NET中的对象转换为JSON字符串(序列化),或者将JSON字符串转换为.NET中已有类型的对象(反序列化?)。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- 不推荐用
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格式——先抓包看它真正要的是 还是 。









