There are a number of ways to do this using the standard API. (Insert your own caveats about verbosity and the factory pattern.)
You can use the XMLStreamWriter to encode the data:
XMLOutputFactory factory = XMLOutputFactory
.newInstance();
XMLStreamWriter writer = factory.createXMLStreamWriter(
stream, "UTF-8");
try {
writer.writeStartDocument("UTF-8", "1.0");
writer.writeStartElement("pie");
for (Entry<String, String> entry : map.entrySet()) {
writer.writeStartElement("slice");
writer.writeAttribute("title", entry.getKey());
writer.writeCharacters(entry.getValue());
writer.writeEndElement();
}
writer.writeEndElement();
writer.writeEndDocument();
} finally {
writer.close();
}
Alternatively, you could build a DOM document (not recommended) and emit that, or use JAXB binding to marshal/unmarshal data (tutorial).
Sample annotated JAXB object:
@XmlRootElement(name = "pie")
public class Pie {
@XmlElement(name = "slice")
public List<Slice> slices = new ArrayList<Slice>();
public Pie() {
}
public Pie(Map<String, String> sliceMap) {
for (Map.Entry<String, String> entry : sliceMap
.entrySet()) {
Slice slice = new Slice();
slice.title = entry.getKey();
slice.value = entry.getValue();
slices.add(slice);
}
}
static class Slice {
@XmlAttribute
public String title;
@XmlValue
public String value;
}
}
Test code:
Map<String, String> slices = new HashMap<String, String>();
slices.put("Title 1", "100");
slices.put("Title 2", "200");
Pie pie = new Pie(slices);
JAXB.marshal(pie, System.out);
There are a host of third party APIs that can do the same jobs and various templating options have already been mentioned.