1. Introduction
1.导言
XML is one of the popular formats for data interchange over the internet. When working with XML data, it’s common to convert it into a more usable format for further processing.
XML 是互联网上数据交换的流行格式之一。在处理 XML 数据时,通常需要将其转换成更可用的格式,以便进一步处理。
In this tutorial, we’ll explore the different ways to parse XML into a HashMap, a data structure that allows for efficient data retrieval and manipulation.
在本教程中,我们将探讨将 XML 解析为 HashMap 的不同方法,这是一种可实现高效数据检索和操作的数据结构。
2. Setup
2.设置
We’ll parse the following XML into a HashMap using different libraries:
我们将使用不同的库将以下 XML 解析为 HashMap 文件:
<employees>
<employee>
<id>654</id>
<firstName>John</firstName>
<lastName>Doe</lastName>
</employee>
<employee>
<id>776</id>
<firstName>Steve</firstName>
<lastName>Smith</lastName>
</employee>
</employees>
Let’s use the below POJO to store the XML data:
让我们使用下面的 POJO 来存储 XML 数据:
public class Employee {
private String id;
private String firstName;
private String lastName;
// standard getters and setters
}
We’ll set up our common test method to validate our results for all the cases:
我们将设置通用测试方法,以验证所有案例的结果:
void verify(Map<String, Employee> employeeMap) {
Employee employee1 = employeeMap.get("654");
Employee employee2 = employeeMap.get("776");
Assertions.assertEquals("John", employee1.getFirstName());
Assertions.assertEquals("Doe", employee1.getLastName());
Assertions.assertEquals("Steve", employee2.getFirstName());
Assertions.assertEquals("Smith", employee2.getLastName());
}
3. Parse XML Using XStream
3.使用 XStream 解析 XML
XStream is a third-party library to serialize and deserialize objects to and from XML. With minimal configuration, XStream provides us with the ability to parse XML data.
XStream 是一个第三方库,用于将对象序列化和反序列化为 XML 或从 XML 反序列化对象。只需极少的配置,XStream 就能为我们提供解析 XML 数据的能力。
We’ll use the below Maven dependency:
我们将使用下面的 Maven 依赖关系:
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.18</version>
</dependency>
We’ll create a new instance of XStream and set up some aliases:
我们将创建一个新的 XStream 实例,并设置一些别名:
XStream xStream=new XStream();
xStream.alias("employees", List.class);
xStream.alias("employee", Employee.class);
We set an alias for the employees element in the XML to be interpreted as a List. We also set an alias for the employee element to be interpreted as an Employee object.
我们为 XML 中的 employees 元素设置了一个别名,将其解释为 List 。我们还为 employee 元素设置了一个别名,将其解释为 Employee 对象。
We’ll add permission to allow any type to be unmarshaled, which is required by XStream for deserializing XML into a list of objects:
我们将添加权限,允许解除任何类型的标记,这是 XStream 将 XML 反序列化为对象列表所必需的:
xStream.addPermission(AnyTypePermission.ANY);
Let’s parse the XML string into a list of Employee objects using XStream’s fromXML() method:
让我们使用 XStream 的 fromXML() 方法将 XML 字符串解析为 Employee 对象列表:
List<Employee> employees = (List<Employee>) xStream.fromXML(xml);
We then convert the list of employees into a Map, using the id as the key and the employee object itself as the value, using streams:
然后,我们使用 streams 将雇员列表转换为 Map 对象,使用 id 作为键,使用 employee 对象本身作为值:
employees.stream().collect(Collectors.toMap(Employee::getId, Function.identity()))
4. Parse XML Using Underscore-java
4.使用 Underscore-java 解析 XML
Underscore-java is a utility library providing a wide range of functional programming and data manipulation functions. It requires Java 11 or higher.
Underscore-java是一个实用程序库,提供广泛的函数式编程和数据操作功能。它需要 Java 11 或更高版本。
We’ll use the below Maven dependency:
我们将使用下面的 Maven 依赖关系:
<dependency>
<groupId>com.github.javadev</groupId>
<artifactId>underscore</artifactId>
<version>1.89</version>
</dependency>
Let’s use Underscore-java’s fromXmlMap() function to parse the XML string and convert it into a nested map structure:
让我们使用 Underscore-java的fromXmlMap()函数来解析 XML 字符串并将其转换为嵌套映射结构:
Map<String, Object> employeeList = (Map<String, Object>)U.fromXmlMap(xml).get("employees");
List<LinkedHashMap<String, String>> list=(List<LinkedHashMap<String,String>>)employeeList.get("employee");
parseXmlToMap(employeeMap, list);
We extract the employees element from the resulting map. We then convert the resulting LinkedHashMap to a HashMap:
我们从生成的映射中提取 employees 元素。然后,我们将生成的 LinkedHashMap 转换为 HashMap :
void parseXmlToMap(Map<String, Employee> employeeMap, List<LinkedHashMap<String, String>> list) {
list.forEach(empMap -> {
Employee employee = new Employee();
for (Map.Entry<String, String> key : empMap.entrySet()) {
switch (key.getKey()) {
case "id":
employee.setId(key.getValue());
break;
case "firstName":
employee.setFirstName(key.getValue());
break;
case "lastName":
employee.setLastName(key.getValue());
break;
default:
break;
}
}
employeeMap.put(employee.getId(), employee);
});
}
Once we have our nested map structure we iterate over each LinkedHashMap in the list, representing an individual employee’s data. We then create a new Employee object and populate its fields based on the data in the map.
一旦我们有了嵌套的映射结构,我们就会遍历列表中的每个 LinkedHashMap 对象,它们代表了单个员工的数据。然后,我们创建一个新的 Employee 对象,并根据映射表中的数据填充其字段。
5. Parse XML Using Jackson
5.使用 Jackson 解析 XML
Jackson is a Java library that seamlessly maps XML elements and attributes to Java objects using annotations or customizable configuration.
Jackson 是一个 Java 库,可使用注释或可定制的配置将 XML 元素和属性无缝映射到 Java 对象。
We’ll use the following Maven dependencies:
我们将使用以下 Maven 依赖项:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
XmlMapper is a specialized mapper for XML data, which allows us to read and write XML:
XmlMapper 是一个专门用于 XML 数据的映射器,它允许我们读写 XML:
XmlMapper xmlMapper = new XmlMapper();
Map<String, Object> map= xmlMapper.readValue(xml, Map.class);
We read the XML data and convert it into a map of key-value pairs. Jackson dynamically parses the XML and builds the corresponding map structure. We extract the list of employee elements from the map:
我们读取 XML 数据并将其转换为键值对映射。Jackson 会动态解析 XML 并构建相应的映射结构:
List<LinkedHashMap<String, String>> list= (List<LinkedHashMap<String, String>>) map.get("employee");
We can then use the same parseXmlToMap() method defined earlier to extract a map of employees.
然后,我们可以使用前面定义的 parseXmlToMap() 方法来提取雇员映射。
6. Parse XML Using JAXB
6.使用 JAXB 解析 XML
JAXB is the Java Architecture for XML binding and it supports a binding framework that maps XML elements and attributes to Java using annotations.
JAXB是用于 XML 绑定的 Java 架构,它支持一个绑定框架,可使用注解将 XML 元素和属性映射到 Java。
We’ll use the following Maven dependency:
我们将使用以下 Maven 依赖关系:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.3</version>
</dependency>
Let’s set up the Employees class with the following annotations to help bind it to the Java object:
让我们用以下注解来设置 Employees 类,以帮助将其绑定到 Java 对象:
@XmlRootElement(name = "employees")
public class Employees {
private List<Employee> employeeList;
@XmlElement(name = "employee")
public List<Employee> getEmployeeList() {
return employeeList;
}
// standard setter
}
Let’s create a JAXBContext which is used to manage the binding between XML data and Java objects:
让我们创建一个 JAXBContext,用于管理 XML 数据和 Java 对象之间的绑定:
JAXBContext context = JAXBContext.newInstance(Employees.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Employees employees = (Employees) unmarshaller.unmarshal(new StringReader(xmlData));
The Unmarshaller is responsible for converting XML data into objects based on the mapping defined by JAXB annotations in the classes.
Unmarshaller负责根据类中的 JAXB 注释所定义的映射将 XML 数据转换为对象。
We convert the list of employees into a Map, using the id as the key and the employee object itself as the value, using Java Streams as done in the earlier section.
我们使用 Java Streams 将雇员列表转换为 Map ,将 id 作为键,将 employee 对象本身作为值。
7. Parse XML Using DOM Parser and XPath
7. 使用 DOM 解析器和 XPath 解析 XML
DOM Parser is a way to parse XML without any third-party libraries. DOM Parser supports XPath for navigating through XML and extracting data.
DOM解析器是一种无需任何第三方库即可解析XML的方法。DOM 解析器支持 XPath,用于导航 XML 和提取数据。
Let’s create a factory for producing DOM parsers, which will be used to parse the XML document:
让我们创建一个生产 DOM 解析器的工厂,用来解析 XML 文档:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlData)));
We parse the XML data into a Document object using the builder responsible for building the DOM representation of the XML.
我们使用负责构建 XML DOM 表示形式的构建器,将 XML 数据解析为 Document 对象。
We’ll then set up an XPath instance to query the DOM:
然后,我们将建立一个 XPath 实例来查询 DOM:
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression xPathExpr = xpath.compile("/employees/employee");
We configure an XPath instance that compiles an XPath expression that selects all employee elements within the employees element in the XML document.
我们配置了一个 XPath 实例,该实例可编译一个 XPath 表达式,以选择 XML 文档中 employees 元素内的所有 employee 元素。
Let’s evaluate the XPath expression on doc to retrieve a NodeList containing all matched employee elements:
让我们评估 doc 上的 XPath 表达式,以检索包含所有匹配雇员元素的 NodeList :
NodeList nodes = (NodeList) xPathExpr.evaluate(doc, XPathConstants.NODESET);
We iterate over the NodeList and extract the employee elements into a HashMap:
我们遍历 NodeList 并将雇员元素提取到 HashMap 中:
for (int i = 0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
Employee employee = new Employee();
employee.setId(node.getElementsByTagName("id").item(0).getTextContent());
employee.setFirstName(node.getElementsByTagName("firstName").item(0).getTextContent());
employee.setLastName(node.getElementsByTagName("lastName").item(0).getTextContent());
map.put(employee.getId(), employee);
}
8. Conclusion
8.结论
In this article, we explored the diverse methods of parsing XML into HashMap, a fundamental data structure for storing key-value pairs.
在本文中,我们探讨了将 XML 解析为 HashMap 的各种方法,这是一种用于存储键值对的基本数据结构。
XStream and Underscore, with their minimal configuration, are ideal for straightforward XML parsing.
XStream 和 Underscore 配置最少,是直接解析 XML 的理想选择。
Jackson seamlessly maps XML elements to Java objects, offering flexibility and ease of use.
Jackson 无缝地将 XML 元素映射到 Java 对象,提供了灵活性和易用性。
JAXB, with its annotations, excels in scenarios demanding a standardized mapping approach.
JAXB 及其注释在需要标准化映射方法的场景中表现出色。
Meanwhile, DOM parsing with XPath provides fine-grained control over XML elements.
同时,使用 XPath 进行 DOM 解析可对 XML 元素进行细粒度控制。
As always the code for the examples is available over on GitHub.
在 GitHub 上提供了这些示例的代码。