Xml in Mercury
Here’s the translation of the XML example from Go to Java, formatted in Markdown suitable for Hugo:
import javax.xml.bind.annotation.*;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
// Plant will be mapped to XML. We use JAXB annotations to specify
// XML element names, attributes, etc.
@XmlRootElement(name = "plant")
@XmlAccessorType(XmlAccessType.FIELD)
class Plant {
@XmlAttribute
private int id;
@XmlElement
private String name;
@XmlElement(name = "origin")
private List<String> origin;
// Default constructor is needed for JAXB
public Plant() {}
public Plant(int id, String name, String... origin) {
this.id = id;
this.name = name;
this.origin = Arrays.asList(origin);
}
@Override
public String toString() {
return String.format("Plant id=%d, name=%s, origin=%s",
id, name, origin);
}
}
public class XMLExample {
public static void main(String[] args) throws Exception {
Plant coffee = new Plant(27, "Coffee", "Ethiopia", "Brazil");
// Create a JAXBContext and Marshaller for XML serialization
JAXBContext context = JAXBContext.newInstance(Plant.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// Serialize the coffee plant to XML
StringWriter writer = new StringWriter();
marshaller.marshal(coffee, writer);
String xmlOutput = writer.toString();
System.out.println(xmlOutput);
// To add a generic XML header to the output, prepend it manually
System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + xmlOutput);
// Use Unmarshaller to parse XML back into a Plant object
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader reader = new StringReader(xmlOutput);
Plant p = (Plant) unmarshaller.unmarshal(reader);
System.out.println(p);
Plant tomato = new Plant(81, "Tomato", "Mexico", "California");
// The parent>child>plant structure can be represented using nested classes
@XmlRootElement(name = "nesting")
@XmlAccessorType(XmlAccessType.FIELD)
class Nesting {
@XmlElementWrapper(name = "parent")
@XmlElementWrapper(name = "child")
@XmlElement(name = "plant")
private List<Plant> plants;
public Nesting(Plant... plants) {
this.plants = Arrays.asList(plants);
}
}
Nesting nesting = new Nesting(coffee, tomato);
// Serialize the nesting object to XML
writer = new StringWriter();
JAXBContext nestingContext = JAXBContext.newInstance(Nesting.class);
Marshaller nestingMarshaller = nestingContext.createMarshaller();
nestingMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
nestingMarshaller.marshal(nesting, writer);
System.out.println(writer.toString());
}
}
This Java code demonstrates XML serialization and deserialization using JAXB (Java Architecture for XML Binding). Here’s a breakdown of the key points:
We define a
Plant
class with JAXB annotations to specify how it should be mapped to XML.The
main
method creates aPlant
object and demonstrates XML serialization usingJAXBContext
andMarshaller
.We show how to add an XML header to the output manually.
XML deserialization is demonstrated using
Unmarshaller
.To represent nested XML structures (like the
parent>child>plant
in the original example), we use a nestedNesting
class with appropriate JAXB annotations.Finally, we serialize the nested structure to XML.
To run this program, save it as XMLExample.java
, compile it with javac XMLExample.java
, and run it with java XMLExample
. The output will show the XML representations of the Plant
and Nesting
objects.
Note that Java’s XML handling is more verbose than the Go example, primarily due to the use of annotations and the JAXB API. However, it provides a powerful and flexible way to work with XML in Java applications.