properties.loadfromxml仅支持特定xml结构,即根元素为且声明正确编码;非标准xml应改用documentbuilder或jaxb解析。

Java里用Properties加载XML失败:不是所有loadFromXML都能读任意XML
Java的Properties类支持XML格式,但只认特定结构——必须是<?xml version="1.0" encoding="UTF-8"?><properties version="1.0">...</properties>这种根节点+固定属性的格式。随便丢个<config><db.url>...</db.url></config>进去,会直接抛InvalidPropertiesFormatException。
- 用
loadFromXML(InputStream)前,先确认XML是否由storeToXML生成,或手动按规范补全<properties version="1.0"></properties>外层 - 非标准XML(比如Spring配置、自定义配置)别硬套
Properties,改用DocumentBuilder或JAXB更稳妥 - 编码问题常被忽略:XML声明里的
encoding必须和实际文件编码一致,否则loadFromXML可能静默乱码
把Properties存成XML时中文乱码:关键在OutputStreamWriter没指定编码
storeToXML默认用系统平台编码写入,不是UTF-8。Windows上跑很可能存出GBK编码的XML,再用UTF-8读就崩。
- 别直接传
FileOutputStream给storeToXML,要包一层OutputStreamWriter并显式指定StandardCharsets.UTF_8 - 第二个参数(注释)如果含中文,也得确保它本身是UTF-8字符串,别从GBK字节流decode过来
- 生成的XML头部
encoding="UTF-8"必须和实际写入编码严格一致,否则其他工具(如Pythonxml.etree)读取会报错
XML转Properties时key重复怎么处理:原生API不合并,靠自己预处理
Properties底层是Hashtable,同名key后出现的值会覆盖前面的。而XML里可能有多个同名<entry key="timeout"></entry>(比如不同profile片段),原生loadFromXML只会留最后一个。
- 想保留全部?不能依赖
Properties,得用DocumentBuilder解析XML,遍历<entry></entry>节点,自己用Map<string list>></string>收集 - 若只是避免覆盖,可在加载前用XSLT或正则把重复key重命名(如
timeout.1、timeout.2) - 注意
entry节点的key属性值如果含空格或特殊字符,Properties虽能存,但后续用getProperty取时可能因未trim导致匹配失败
用javax.xml.bind.JAXB做双向转换太重:轻量替代方案只有手写解析器
JAXB在JDK 11+已移除,加依赖又引入一堆XML绑定规则,对纯键值对转换属于杀鸡用牛刀。真要灵活互转,不如直接用DocumentBuilder + Properties组合。
立即学习“Java免费学习笔记(深入)”;
- XML→Properties:用
DocumentBuilder解析,循环getElementsByTagName("entry"),提取key属性和文本内容,put进Properties - Properties→XML:遍历
propertyNames(),手动拼装<entry key="xxx">yyy</entry>节点,再包装成标准<properties></properties>根 - 性能上,小文件(StAX(
XMLStreamReader)替代DOM,避免内存暴涨
真正麻烦的从来不是语法,而是XML里那些没明说的隐含约束:根节点名、version属性、编码声明、key唯一性假设……这些地方一错,错误信息往往只报“invalid format”,得往底层源码里翻才明白到底卡在哪。










