Java XML 转 Map 的几种方法
在 Java 中将 XML 转换为 Map 是一个常见的需求,以下是几种实现方式:
使用 DOM 解析器
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
import java.util.*;
public class XmlToMapConverter {
public static Map<String, Object> xmlToMap(String xmlString) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xmlString)));
Map<String, Object> map = new HashMap<>();
NodeList nodeList = document.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
map.put(node.getNodeName(), node.getTextContent());
}
}
return map;
}
}
使用 Jackson 库
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.util.*;
public class XmlToMapConverter {
public static Map<String, Object> xmlToMap(String xmlString) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
return xmlMapper.readValue(xmlString, new TypeReference<Map<String, Object>>() {});
}
}
使用 XStream 库
import com.thoughtworks.xstream.XStream;
import java.util.*;
public class XmlToMapConverter {
public static Map<String, Object> xmlToMap(String xmlString) {
XStream xstream = new XStream();
xstream.alias("map", HashMap.class);
xstream.alias("entry", Map.Entry.class);
xstream.registerConverter(new MapEntryConverter());
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) xstream.fromXML(xmlString);
return map;
}
}
class MapEntryConverter implements Converter {
// 实现Converter接口方法...
}
使用 Simple XML 库
import org.simpleframework.xml.*;
import org.simpleframework.xml.convert.*;
import org.simpleframework.xml.stream.*;
import java.util.*;
@Root
public class XmlToMapConverter {
@ElementMap(entry = "entry", key = "key", value = "value", inline = true)
private Map<String, Object> map;
public static Map<String, Object> xmlToMap(String xmlString) throws Exception {
Serializer serializer = new Persister();
XmlToMapConverter converter = serializer.read(XmlToMapConverter.class, xmlString);
return converter.map;
}
}
使用 Apache Commons Digester
import org.apache.commons.digester3.Digester;
import java.util.*;
public class XmlToMapConverter {
public static Map<String, Object> xmlToMap(String xmlString) throws Exception {
Digester digester = new Digester();
Map<String, Object> map = new HashMap<>();
digester.push(map);
digester.addSetNext("*/entry", "put");
digester.addObjectCreate("*/entry", HashMap.class);
digester.addSetProperties("*/entry", "key", "key");
digester.addSetNext("*/entry/value", "put");
return digester.parse(new InputSource(new StringReader(xmlString)));
}
}
注意事项
- 嵌套结构处理:上述方法中,只有 Jackson 和 XStream 能很好地处理嵌套的 XML 结构
- 命名空间:XML 使用命名空间,需要额外处理
- 属性:有些方法可能无法自动处理 XML 属性
- 性能:对于大文件,DOM 解析器可能不是最佳选择,考虑使用 SAX 或 StAX
完整示例(Jackson 处理嵌套结构)
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.util.*;
public class XmlToMapConverter {
public static Map<String, Object> xmlToMap(String xmlString) throws Exception {
XmlMapper xmlMapper = new XmlMapper();
return xmlMapper.readValue(xmlString, new TypeReference<Map<String, Object>>() {});
}
public static void main(String[] args) throws Exception {
String xml = "<root><name>John</name><age>30</age><address><street>123 Main St</street><city>New York</city></address></root>";
Map<String, Object> map = xmlToMap(xml);
System.out.println(map);
// 输出: {name=John, age=30, address={street=123 Main St, city=New York}}
}
}
选择哪种方法取决于你的具体需求,如 XML 结构复杂度、性能要求和项目依赖情况,Jackson 通常是处理 XML 到 Map 转换的最简单和最灵活的方法。
