diff --git a/xml-2/pom.xml b/xml-2/pom.xml
index 0f94588ba0..ccb84e1687 100644
--- a/xml-2/pom.xml
+++ b/xml-2/pom.xml
@@ -46,6 +46,16 @@
underscore
${underscore.version}
+
+ com.thoughtworks.xstream
+ xstream
+ ${xstream.version}
+
+
+ com.sun.xml.bind
+ jaxb-impl
+ ${jaxb.version}
+
org.apache.xmlbeans
xmlbeans
@@ -82,6 +92,8 @@
2.1.3
20230227
1.89
+ 1.4.18
+ 2.3.3
diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java
new file mode 100644
index 0000000000..c9c40e743a
--- /dev/null
+++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employee.java
@@ -0,0 +1,31 @@
+package com.baeldung.xml.tohashmap;
+
+public class Employee {
+ private String id;
+ private String firstName;
+ private String lastName;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java
new file mode 100644
index 0000000000..d2f2276e5c
--- /dev/null
+++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/Employees.java
@@ -0,0 +1,21 @@
+package com.baeldung.xml.tohashmap;
+
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement(name = "employees")
+public class Employees {
+
+ private List employeeList;
+
+ @XmlElement(name = "employee")
+ public List getEmployeeList() {
+ return employeeList;
+ }
+
+ public void setEmployeeList(List employeeList) {
+ this.employeeList = employeeList;
+ }
+}
\ No newline at end of file
diff --git a/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java
new file mode 100644
index 0000000000..ec651486ac
--- /dev/null
+++ b/xml-2/src/main/java/com/baeldung/xml/tohashmap/XmlToHashMap.java
@@ -0,0 +1,124 @@
+package com.baeldung.xml.tohashmap;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.dataformat.xml.XmlMapper;
+import com.github.underscore.U;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.security.AnyTypePermission;
+
+public class XmlToHashMap {
+
+ public Map xmlToHashMapUsingXstream(String xml) {
+ XStream xStream = new XStream();
+ xStream.alias("employees", List.class);
+ xStream.alias("employee", Employee.class);
+ xStream.addPermission(AnyTypePermission.ANY);
+ List employees = (List) xStream.fromXML(xml);
+ return employees.stream()
+ .collect(Collectors.toMap(Employee::getId, Function.identity()));
+ }
+
+ public Map xmlToHashMapUsingUnderscore(String xml) {
+ Map employeeMap = new HashMap<>();
+ Map employeeList = (Map) U.fromXmlMap(xml)
+ .get("employees");
+ List> list = (List>) employeeList.get("employee");
+ parseXmlToMap(employeeMap, list);
+ return employeeMap;
+ }
+
+ public Map xmlToHashMapUsingJackson(String xml) throws JsonProcessingException {
+ XmlMapper xmlMapper = new XmlMapper();
+ Map employeeMap = new HashMap<>();
+ Map map = xmlMapper.readValue(xml, Map.class);
+ List> list = (List>) map.get("employee");
+ parseXmlToMap(employeeMap, list);
+ return employeeMap;
+ }
+
+ public Map xmlToHashMapUsingJAXB(String xmlData) throws JAXBException {
+ JAXBContext context = JAXBContext.newInstance(Employees.class);
+ Unmarshaller unmarshaller = context.createUnmarshaller();
+ Employees employees = (Employees) unmarshaller.unmarshal(new StringReader(xmlData));
+ return employees.getEmployeeList()
+ .stream()
+ .collect(Collectors.toMap(Employee::getId, Function.identity()));
+ }
+
+ public Map xmlToHashMapUsingDOMParserXpath(String xmlData) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ Document doc = builder.parse(new InputSource(new StringReader(xmlData)));
+
+ XPathFactory xPathfactory = XPathFactory.newInstance();
+ XPath xpath = xPathfactory.newXPath();
+ XPathExpression xPathExpr = xpath.compile("/employees/employee");
+ NodeList nodes = (NodeList) xPathExpr.evaluate(doc, XPathConstants.NODESET);
+
+ HashMap map = new 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);
+ }
+ return map;
+ }
+
+ private static void parseXmlToMap(Map employeeMap, List> list) {
+ list.forEach(empMap -> {
+ Employee employee = new Employee();
+ for (Map.Entry 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);
+ });
+ }
+}
diff --git a/xml-2/src/main/resources/xml/xmltohashmap/test.xml b/xml-2/src/main/resources/xml/xmltohashmap/test.xml
new file mode 100644
index 0000000000..ef0d12e2af
--- /dev/null
+++ b/xml-2/src/main/resources/xml/xmltohashmap/test.xml
@@ -0,0 +1,12 @@
+
+
+ 654
+ John
+ Doe
+
+
+ 776
+ Steve
+ Smith
+
+
\ No newline at end of file
diff --git a/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java
new file mode 100644
index 0000000000..5e05dd3ccb
--- /dev/null
+++ b/xml-2/src/test/java/com/baeldung/xml/tohashmap/XmlToHashMapUnitTest.java
@@ -0,0 +1,71 @@
+package com.baeldung.xml.tohashmap;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Map;
+
+import javax.xml.bind.JAXBException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class XmlToHashMapUnitTest {
+
+ private XmlToHashMap xmlToHashMap;
+ private static final String TEST_XML_PATH = "src/main/resources/xml/xmltohashmap/test.xml";
+
+ @BeforeEach
+ void setUp() {
+ xmlToHashMap = new XmlToHashMap();
+ }
+
+ @Test
+ void whenUsingXstream_thenHashMapShouldBeCreated() throws IOException {
+ Map employeeMap = xmlToHashMap.xmlToHashMapUsingXstream(getXml());
+ verify(employeeMap);
+ }
+
+ @Test
+ void whenUsingUnderscore_thenHashMapShouldBeCreated() throws IOException {
+ Map employeeMap = xmlToHashMap.xmlToHashMapUsingUnderscore(getXml());
+ verify(employeeMap);
+ }
+
+ @Test
+ void whenUsingJackson_thenHashMapShouldBeCreated() throws IOException {
+ Map employeeMap = xmlToHashMap.xmlToHashMapUsingJackson(getXml());
+ verify(employeeMap);
+ }
+
+ @Test
+ void whenUsingJAXB_thenHashMapShouldBeCreated() throws IOException, JAXBException {
+ Map employeeMap = xmlToHashMap.xmlToHashMapUsingJAXB(getXml());
+ verify(employeeMap);
+ }
+
+ @Test
+ void whenUsingDOMXpath_thenHashMapShouldBeCreated() throws Exception {
+ Map employeeMap = xmlToHashMap.xmlToHashMapUsingDOMParserXpath(getXml());
+ verify(employeeMap);
+ }
+
+ private void verify(Map 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());
+ }
+
+ private String getXml() throws IOException {
+ return new String(Files.readAllBytes(Paths.get(TEST_XML_PATH)));
+ }
+}