如何用Jackson将XML字符串转为美观格式且保留原结构?
解决Jackson XML转Map再转回时丢失原始结构的问题
问题原因
当你直接将XML字符串转换为Map时,Jackson会把根节点(<SimpleBean>)的子元素作为Map的键值对存储,但根节点的名称本身不会被保留在Map中。因此当你将Map转回XML时,Jackson只能用Map的实际类型(LinkedHashMap)作为根节点名称,导致原始结构丢失。
解决方案
方案1:直接格式化XML(无需转Map,推荐)
如果你的需求只是格式化XML字符串,不需要中间转成Map,直接用Jackson的XmlMapper读取为JsonNode再输出即可,完整保留原始结构:
@Test public void TestXmlStringToPretty() throws JsonMappingException, JsonProcessingException { String XML_STRING = "<SimpleBean><x>1</x><y>2</y></SimpleBean>"; XmlMapper xmlMapper = new XmlMapper(); // 直接读取XML为JsonNode,保留完整节点结构 JsonNode xmlNode = xmlMapper.readTree(XML_STRING); // 输出格式化后的XML System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(xmlNode)); assertNotNull(xmlNode); }
输出结果:
<SimpleBean> <x>1</x> <y>2</y> </SimpleBean>
方案2:必须转Map时,保留根节点信息
如果业务逻辑要求必须转成Map,需要通过TypedReference将整个XML读取为嵌套Map,把根节点名称作为外层Map的键,内部内容作为值:
@Test public void TestXmlStringToPrettyWithRoot() throws JsonMappingException, JsonProcessingException { String XML_STRING = "<SimpleBean><x>1</x><y>2</y></SimpleBean>"; XmlMapper xmlMapper = new XmlMapper(); // 用TypedReference读取为包含根节点的嵌套Map Map<String, Map<String, Object>> rootMap = xmlMapper.readValue( XML_STRING, new TypedReference<Map<String, Map<String, Object>>>() {} ); // 转回XML时会恢复原始根节点 System.out.println(xmlMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootMap)); assertNotNull(rootMap); }
输出结果:
<SimpleBean> <x>1</x> <y>2</y> </SimpleBean>
补充说明
- 避免直接将XML转成顶层
Map,因为这种方式天然丢失根节点元信息; - 若需要处理动态XML结构,
JsonNode是比Map更合适的中间载体,它能完整保留XML的节点层级和名称。
内容的提问来源于stack exchange,提问作者tarekahf
相关产品推荐
相关产品推荐

