how to parse xml to hashmap?
Use JAXB
to read from xml
and save it to a custom object.
Custom object class:
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@XmlRootElement(name = "Details")
@XmlType(propOrder = { "detailA", "detailB" })
public class Details {
private List<String> detailA;
private List<String> detailB;
public void setDetailA(List<String> detailA) {
this.detailA = detailA;
}
@XmlElementWrapper(name = "detail-a")
@XmlElement(name = "detail")
public List<String> getDetailA() {
return detailA;
}
public void setDetailB(List<String> detailB) {
this.detailB = detailB;
}
@XmlElementWrapper(name = "detail-b")
@XmlElement(name = "detail")
public List<String> getDetailB() {
return detailB;
}
}
Extract the data from your xml into the object, then add contents to a map as desired:
public static void main(String[] args) throws JAXBException, FileNotFoundException {
System.out.println("Output from our XML File: ");
JAXBContext context = JAXBContext.newInstance(Details.class);
Unmarshaller um = context.createUnmarshaller();
Details details = (Details)um.unmarshal(new FileReader("details.xml"));
List<String> detailA = details.getDetailA();
List<String> detailB = details.getDetailB();
Map<String, String[]> map = new HashMap<String, String[]>();
map.put("detail-a", detailA.toArray(new String[detailA.size()]));
map.put("detail-b", detailB.toArray(new String[detailB.size()]));
for (Map.Entry<String, String[]> entry : map.entrySet()) {
//key "detail a" value={"attribute 1 of detail a","attribute 2 of detail a","attribute 3 of detail a"}
System.out.print("Key \"" +entry.getKey()+"\" value={");
for(int i=0;i<entry.getValue().length;i++){
if(i!=entry.getValue().length-1){
System.out.print("\""+entry.getValue()[i]+"\",");
}
else{
System.out.print("\""+entry.getValue()[i]+"\"}");
}
}
System.out.println();
}
}
Output will be:
Output from our XML File: Key "detail-a" value={"attribute 1 of detail a","attribute 2 of detail a","attribute 3 of detail a"} Key "detail-b" value={"attribute 1 of detail b","attribute 2 of detail b"}
As a note: this will work only for the xml you provided as input in your question, if you need to add more details like detail-c
and so on you must define them in your custom object as well.
XML used:
<?xml version="1.0" encoding="utf-8"?>
<Details>
<detail-a>
<detail>attribute 1 of detail a</detail>
<detail>attribute 2 of detail a</detail>
<detail>attribute 3 of detail a</detail>
</detail-a>
<detail-b>
<detail>attribute 1 of detail b</detail>
<detail>attribute 2 of detail b</detail>
</detail-b>
</Details>
I can not resist to present a much shorter solution using XMLBeam that works with any number of "detail-x" subelements.
public class Tetst {
@XBDocURL("resource://test.xml")
public interface Projection {
@XBRead("name()")
String getName();
@XBRead("./detail")
List<String> getDetailStrings();
@XBRead("/Details/*")
List<Projection> getDetails();
}
@Test
public void xml2Hashmap() throws IOException {
HashMap<String, List<String>> hashmap = new HashMap<String, List<String>>();
for (Projection p : new XBProjector().io().fromURLAnnotation(Projection.class).getDetails()) {
System.out.println(p.getName() + ": " + p.getDetailStrings());
hashmap.put(p.getName(), p.getDetailStrings());
}
}
}
This prints out
detail-a: [ attribute 1 of detail a , attribute 2 of detail a , attribute 3 of detail a ]
detail-b: [ attribute 1 of detail b , attribute 2 of detail b ]
for your example test.xml and fills a Hashmap.
There is underscore-java library. I am the maintainer of the project. Live example
import com.github.underscore.lodash.U;
import java.util.Map;
public class Main {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
Map<String, Object> map = U.fromXmlMap(
"<Details>\r\n" +
" <detail-a>\r\n" +
"\r\n" +
" <detail> attribute 1 of detail a </detail>\r\n" +
" <detail> attribute 2 of detail a </detail>\r\n" +
" <detail> attribute 3 of detail a </detail>\r\n" +
"\r\n" +
" </detail-a>\r\n" +
"\r\n" +
" <detail-b>\r\n" +
" <detail> attribute 1 of detail b </detail>\r\n" +
" <detail> attribute 2 of detail b </detail>\r\n" +
"\r\n" +
" </detail-b>\r\n" +
"\r\n" +
"\r\n" +
"</Details>");
System.out.println(map);
// {Details={detail-a={detail=[ attribute 1 of detail a , attribute 2 of detail a , attribute 3 of detail a ]},
// detail-b={detail=[ attribute 1 of detail b , attribute 2 of detail b ]}}, #omit-xml-declaration=yes}
}
}