Java中XML转JSON时如何保留插入顺序?
解决XML转JSON/LinkedHashMap时保留插入顺序的方案
方案1:修改org.json的解析逻辑,生成有序JSONObject
org.json.XML.toJSONObject默认使用无序的HashMap存储数据,你可以自定义解析逻辑,让JSONObject内部用LinkedHashMap来保留顺序:
import org.json.JSONObject; import org.json.XML; import org.json.XMLTokener; import java.util.LinkedHashMap; public class OrderedXMLToJson { public static JSONObject xmlToOrderedJson(String xml) throws Exception { XMLTokener tokener = new XMLTokener(xml); // 初始化JSONObject时传入LinkedHashMap,强制有序存储 JSONObject orderedJson = new JSONObject(new LinkedHashMap<>()); XML.parse(tokener, orderedJson, false); return orderedJson; } }
后续将这个有序JSONObject转成LinkedHashMap时,就能完整保留XML元素的原始顺序。
方案2:用Jackson XML模块直接转LinkedHashMap
既然你已经在用Jackson处理JSON,直接用Jackson的XML模块完成XML到LinkedHashMap的转换,跳过中间JSON步骤,全程保序:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import java.util.LinkedHashMap; public class XmlToLinkedHashMap { public static LinkedHashMap<String, Object> convert(String xml) throws Exception { XmlMapper xmlMapper = new XmlMapper(); // 配置反序列化时用LinkedHashMap存储属性 return xmlMapper.readValue(xml, new com.fasterxml.jackson.core.type.TypeReference<LinkedHashMap<String, Object>>() {}); } }
这种方式和你现有Jackson生态兼容,无需额外引入新的依赖冲突,且能直接保留XML节点的顺序。
方案3:原生DOM解析手动构建LinkedHashMap
如果不想依赖第三方库的特殊配置,用Java原生DOM解析XML,手动遍历节点并按顺序插入LinkedHashMap:
import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.ByteArrayInputStream; import java.util.LinkedHashMap; import java.util.List; import java.util.ArrayList; public class DOMOrderedParser { public static LinkedHashMap<String, Object> parseXmlToOrderedMap(String xml) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); doc.getDocumentElement().normalize(); return parseNode(doc.getDocumentElement()); } private static LinkedHashMap<String, Object> parseNode(Node node) { LinkedHashMap<String, Object> map = new LinkedHashMap<>(); // 处理节点属性 if (node.hasAttributes()) { NodeList attrs = node.getAttributes(); for (int i = 0; i < attrs.getLength(); i++) { Node attr = attrs.item(i); map.put("@" + attr.getNodeName(), attr.getNodeValue()); } } // 处理子节点 NodeList childNodes = node.getChildNodes(); if (childNodes.getLength() == 1 && childNodes.item(0).getNodeType() == Node.TEXT_NODE) { map.put("#text", childNodes.item(0).getNodeValue().trim()); } else { for (int i = 0; i < childNodes.getLength(); i++) { Node child = childNodes.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { String key = child.getNodeName(); Object existing = map.get(key); if (existing == null) { map.put(key, parseNode(child)); } else { // 同名节点转为列表存储 if (!(existing instanceof List)) { List<Object> list = new ArrayList<>(); list.add(existing); list.add(parseNode(child)); map.put(key, list); } else { ((List<Object>) existing).add(parseNode(child)); } } } } } return map; } }
这种方式完全可控,能精准保留XML中属性、子节点的原始顺序,适合对XML结构有特殊处理需求的场景。
内容的提问来源于stack exchange,提问作者Santrupta Dash
相关产品推荐
相关产品推荐

