Using Jackson
library you can read whole XML
payload as List<Map>
and write custom serialiser which will write it in new format. See below example:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator;
import javax.xml.namespace.QName;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
public class XmlMapperApp {
public static void main(String... args) throws Exception {
File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
XmlMapper mapper = XmlMapper.xmlBuilder()
.enable(SerializationFeature.INDENT_OUTPUT)
.enable(ToXmlGenerator.Feature.WRITE_XML_DECLARATION)
.build();
List<Map<String, Object>> items = readOldXmlFormat(xmlFile, mapper);
String xml = writeNewXmlFormat(mapper, items);
System.out.println(xml);
}
private static List<Map<String, Object>> readOldXmlFormat(File xmlFile, XmlMapper mapper) throws IOException {
CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, Map.class);
return mapper.readValue(xmlFile, collectionType);
}
private static String writeNewXmlFormat(XmlMapper mapper, List<Map<String, Object>> items) throws IOException {
return mapper.writeValueAsString(new SerializableItems(items));
}
}
@JacksonXmlRootElement(localName = "Elements")
class SerializableItems implements JsonSerializable {
private final List<Map<String, Object>> items;
SerializableItems(List<Map<String, Object>> items) {
this.items = items;
}
private final QName itemQName = new QName("Item");
private final QName elementQName = new QName("Element");
private final QName entryQName = new QName("Entry");
@Override
public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException {
ToXmlGenerator xmlGen = (ToXmlGenerator) gen;
xmlGen.writeStartObject();
for (Map<String, Object> item : items) {
xmlGen.startWrappedValue(entryQName, itemQName);
xmlGen.startWrappedValue(itemQName, elementQName);
for (Map.Entry<String, Object> entry : item.entrySet()) {
xmlGen.writeObjectField(entry.getKey(), entry.getValue());
}
xmlGen.finishWrappedValue(itemQName, elementQName);
xmlGen.finishWrappedValue(entryQName, itemQName);
}
xmlGen.writeEndObject();
}
@Override
public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
}
}
Above code prints:
<?xml version='1.0' encoding='UTF-8'?>
<Elements>
<Entry>
<Item>
<Element>
<Value>On</Value>
</Element>
</Item>
</Entry>
<Entry>
<Item>
<Element>
<Value>On</Value>
</Element>
</Item>
</Entry>
</Elements>