Reputation: 4606
When I call an api, I get an xml response like this. I need to deserialize this into an object and then serialize it back to an xml of this same format.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Person version= "xyz">
<properties>
<name> John</name>
<city>nyc</city>
</properties>
</Person>
I am facing two challenges
1>The properties has a variable list. I need to serialize this into a Map<String,String>. (key:name->value:John, key:city->value:nyc, etc)
2>When I serialize the Person object back to XML how do I add version= "xyz"
attribute?
Can someone help me?
Upvotes: 0
Views: 1178
Reputation: 159114
You can use JAXB, with @XmlAnyElement
for support of elements with arbitrary names.
The following works natively with Java 8. For Java 7, the stream logic in toString()
needs to be changed to regular for
loop. For Java 9+, where JAXB was removed, a JAXB library is needed.
@XmlRootElement(name = "Person")
@XmlAccessorType(XmlAccessType.NONE)
class Person {
private String version;
private List<Element> properties;
@XmlAttribute
public String getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version = version;
}
@XmlElementWrapper(name = "properties")
@XmlAnyElement
public List<Element> getProperties() {
return this.properties;
}
public void setProperties(List<Element> properties) {
this.properties = properties;
}
public void addProperty(String name, String value) {
try {
Element elem = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().newDocument().createElement(name);
elem.setTextContent(value);
if (this.properties == null)
this.properties = new ArrayList<>();
this.properties.add(elem);
} catch (ParserConfigurationException e) {
throw new IllegalStateException(e);
}
}
@Override
public String toString() {
String propertiesAsString = this.properties.stream()
.map(e -> e.getLocalName() + ": \"" + e.getTextContent() + "\"")
.collect(Collectors.joining(", ", "[", "]"));
return "Person[version=" + this.version + ", properties=" + propertiesAsString + "]";
}
}
Test
Person person = new Person();
person.setVersion("xyz");
person.addProperty("name", " John");
person.addProperty("city", "nyc");
JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter xml = new StringWriter();
marshaller.marshal(person, xml);
System.out.println(xml);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Person person2 = (Person) unmarshaller.unmarshal(new StringReader(xml.toString()));
System.out.println(person2);
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Person version="xyz">
<properties>
<name> John</name>
<city>nyc</city>
</properties>
</Person>
Person[version=xyz, properties=[name: " John", city: "nyc"]]
Upvotes: 2