tags:

views:

238

answers:

3
+2  Q: 

XML using Java

I have to write an XML file using java.The contents should be written from a map.The map contains items as key and their market share as value.I need to build an XML file withe two tags.I will use this XML to build a piechart using amcharts.Can anyone help with an existing code?

<xml>
<pie>
    <slice title="<Map key1>"><Map Value1></slice>
    <slice title="<Map key2>"><Map Value2></slice>
    <slice title="<Map key1>"><Map Value3></slice>
     .
     .
     .
    <slice title="<Map keyn>"><Map Valuen></slice>
 </pie>
+1  A: 

To add to cadrian's answer: You could also use a template engine like FreeMarker. This allows you have the XML as a template outside of your Java code and do the binding between your Java objects and XML inside the template.

willcodejavaforfood
yes, you are right of course. Or Velocity.
cadrian
+2  A: 

I would beware of writing XML directly since you have to worry about entity encoding.

e.g. writing text content with <, > or & directly will generate invalid XML. The same will apply when using Velocity and Freemarker.

If you do write the XML directly, make sure that all your text content gets encoded properly. You can do this using Apache Commons and StringEscapeUtils.escapeXML().

EDIT: Looking again at your XML requirements, XStream may work for you. If you have a java.util.Map, XStream can write this straight out. You'll have to look at aliasing to change your element names, but possibly worth looking at.

Brian Agnew
+2  A: 

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.

McDowell
Fantastic...Marvellous..voted for you
Harish