如何在Java JDK 11中不借助额外库实现HashMap与XML互转?
在Java 11中无额外库实现HashMap与XML的互转
可以实现,Java 11自带的javax.xml包提供了足够的API完成这个需求,以下是具体的实现方案:
1. HashMap 转 XML
利用DOM API构建XML文档,再通过Transformer将文档转换为字符串,支持嵌套HashMap结构:
import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; public class HashMapToXml { public static String convert(HashMap<String, Object> hashMap, String rootName) throws Exception { // 初始化DOM文档 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.newDocument(); // 创建根节点 Element root = doc.createElement(rootName); doc.appendChild(root); // 遍历HashMap生成节点 buildXmlNodes(doc, root, hashMap); // 格式化输出XML字符串 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); StringWriter writer = new StringWriter(); transformer.transform(new DOMSource(doc), new StreamResult(writer)); return writer.toString(); } private static void buildXmlNodes(Document doc, Element parent, HashMap<String, Object> map) { for (Map.Entry<String, Object> entry : map.entrySet()) { Element node = doc.createElement(entry.getKey()); Object value = entry.getValue(); if (value instanceof HashMap) { // 处理嵌套HashMap buildXmlNodes(doc, node, (HashMap<String, Object>) value); } else { node.appendChild(doc.createTextNode(value.toString())); } parent.appendChild(node); } } public static void main(String[] args) throws Exception { HashMap<String, Object> data = new HashMap<>(); data.put("id", "1001"); data.put("username", "alice"); HashMap<String, Object> contact = new HashMap<>(); contact.put("email", "alice@example.com"); contact.put("phone", "123456789"); data.put("contact", contact); System.out.println(convert(data, "user")); } }
2. XML 转 HashMap
通过DocumentBuilder解析XML,递归遍历节点并将数据存入HashMap,支持嵌套结构:
import org.w3c.dom.Document; import org.w3c.dom.Element; 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.HashMap; public class XmlToHashMap { public static HashMap<String, Object> convert(String xml) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); doc.getDocumentElement().normalize(); HashMap<String, Object> result = new HashMap<>(); parseXmlNode(doc.getDocumentElement(), result); return result; } private static void parseXmlNode(Node node, HashMap<String, Object> map) { if (node.getNodeType() != Node.ELEMENT_NODE) { return; } Element element = (Element) node; NodeList childNodes = element.getChildNodes(); // 节点仅包含文本内容 if (childNodes.getLength() == 1 && childNodes.item(0).getNodeType() == Node.TEXT_NODE) { map.put(element.getNodeName(), childNodes.item(0).getNodeValue().trim()); return; } // 节点包含子元素,创建嵌套HashMap HashMap<String, Object> nestedMap = new HashMap<>(); map.put(element.getNodeName(), nestedMap); for (int i = 0; i < childNodes.getLength(); i++) { parseXmlNode(childNodes.item(i), nestedMap); } } public static void main(String[] args) throws Exception { String xml = "<user>\n" + " <id>1001</id>\n" + " <username>alice</username>\n" + " <contact>\n" + " <email>alice@example.com</email>\n" + " <phone>123456789</phone>\n" + " </contact>\n" + "</user>"; System.out.println(convert(xml)); } }
注意事项
- 模块化项目适配:如果使用Java模块系统,需要在
module-info.java中添加requires java.xml;声明依赖 - 特殊字符处理:DOM API会自动处理XML文本中的特殊字符(如
<、>、&),无需手动转义 - 重复节点扩展:若XML存在重复标签名,当前实现会覆盖值,可修改为将值存入
List以支持多节点场景
内容的提问来源于stack exchange,提问作者Sathvik Bellary
相关产品推荐
相关产品推荐

