You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:45:34