如何无需自定义类将XML数据转换为List<Map<String,String>>?
问题描述
给定如下XML数据:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <books> <book> <name>SCJP</name> <author>Kathy Sierra</author> <publisher>Tata McGraw Hill</publisher> <isbn>856-545456736</isbn> </book> <book> <name>Java Persistence with Hibernate</name> <author>Christian Bauer</author> <publisher>Manning</publisher> <isbn>978-3832180577</isbn> </book> </books>
能否无需自定义类,将该XML数据转换为List<Map<String,String>>或List<Map<String,Object>>格式?
此前尝试用JAXB解组,得到的是自定义Book类的对象列表:
[Book [name=SCJP, author=Kathy Sierra, publisher=Tata McGraw Hill, isbn=856-545456736], Book [name=Java Persistence with Hibernate, author=Christian Bauer, publisher=Manning, isbn=978-3832180577]]
期望得到的格式为:
[{name="SCJP", author="Kathy Sierra", publisher="Tata McGraw Hill", isbn="856-545456736"}, {name="Java Persistence with Hibernate", author="Christian Bauer", publisher="Manning", isbn="978-3832180577"}]
解决方案
可以实现,以下是几种无需自定义类的实现方式:
1. JDK原生DOM解析(无额外依赖)
直接使用JDK自带的DOM API遍历XML节点,将每个book节点的子节点键值对存入Map,再收集到List中:
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.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class XmlToMapList { public static void main(String[] args) throws Exception { String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + "<books>\n" + " <book>\n" + " <name>SCJP</name>\n" + " <author>Kathy Sierra</author>\n" + " <publisher>Tata McGraw Hill</publisher>\n" + " <isbn>856-545456736</isbn>\n" + " </book>\n" + " <book>\n" + " <name>Java Persistence with Hibernate</name>\n" + " <author>Christian Bauer</author>\n" + " <publisher>Manning</publisher>\n" + " <isbn>978-3832180577</isbn>\n" + " </book>\n" + "</books>"; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new ByteArrayInputStream(xmlContent.getBytes())); doc.getDocumentElement().normalize(); NodeList bookNodes = doc.getElementsByTagName("book"); List<Map<String, String>> resultList = new ArrayList<>(); for (int i = 0; i < bookNodes.getLength(); i++) { Node bookNode = bookNodes.item(i); if (bookNode.getNodeType() == Node.ELEMENT_NODE) { Element bookElement = (Element) bookNode; Map<String, String> bookMap = new HashMap<>(); NodeList childNodes = bookElement.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node child = childNodes.item(j); if (child.getNodeType() == Node.ELEMENT_NODE) { Element childElement = (Element) child; bookMap.put(childElement.getTagName(), childElement.getTextContent().trim()); } } resultList.add(bookMap); } } // 输出结果 System.out.println(resultList); } }
2. 使用Jackson XML(需引入依赖)
Jackson提供了XML解析支持,可以直接将XML映射为List<Map<String,String>>,无需自定义类:
首先添加Maven依赖:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.15.2</version> </dependency>
实现代码:
import com.fasterxml.jackson.dataformat.xml.XmlMapper; import java.util.List; import java.util.Map; public class JacksonXmlToMapList { public static void main(String[] args) throws Exception { String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + "<books>\n" + " <book>\n" + " <name>SCJP</name>\n" + " <author>Kathy Sierra</author>\n" + " <publisher>Tata McGraw Hill</publisher>\n" + " <isbn>856-545456736</isbn>\n" + " </book>\n" + " <book>\n" + " <name>Java Persistence with Hibernate</name>\n" + " <author>Christian Bauer</author>\n" + " <publisher>Manning</publisher>\n" + " <isbn>978-3832180577</isbn>\n" + " </book>\n" + "</books>"; XmlMapper xmlMapper = new XmlMapper(); // 将XML解析为包含books键的Map,再提取book列表 Map<String, List<Map<String, String>>> resultMap = xmlMapper.readValue(xmlContent, Map.class); List<Map<String, String>> bookList = resultMap.get("book"); // 输出结果 System.out.println(bookList); } }
3. 使用Apache Commons Digester(需引入依赖)
Apache Commons Digester可以通过配置规则将XML解析为Map列表:
添加Maven依赖:
<dependency> <groupId>commons-digester</groupId> <artifactId>commons-digester</artifactId> <version>2.1</version> </dependency>
实现代码:
import org.apache.commons.digester3.Digester; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class DigesterXmlToMapList { public static void main(String[] args) throws Exception { String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + "<books>\n" + " <book>\n" + " <name>SCJP</name>\n" + " <author>Kathy Sierra</author>\n" + " <publisher>Tata McGraw Hill</publisher>\n" + " <isbn>856-545456736</isbn>\n" + " </book>\n" + " <book>\n" + " <name>Java Persistence with Hibernate</name>\n" + " <author>Christian Bauer</author>\n" + " <publisher>Manning</publisher>\n" + " <isbn>978-3832180577</isbn>\n" + " </book>\n" + "</books>"; Digester digester = new Digester(); digester.setValidating(false); // 根节点books对应一个List digester.addObjectCreate("books", ArrayList.class); // 每个book节点创建一个HashMap,加入List digester.addObjectCreate("books/book", HashMap.class); digester.addSetNext("books/book", "add"); // 将book的子节点作为键值对存入HashMap digester.addBeanPropertySetter("books/book/*"); List<Map<String, String>> bookList = digester.parse(new ByteArrayInputStream(xmlContent.getBytes())); // 输出结果 System.out.println(bookList); } }
内容的提问来源于stack exchange,提问作者user3608694
相关产品推荐
相关产品推荐

