I'm serializing Objects to XML with the help of XStream. How do I tell XStream to insert an xmlns to the XML output of my object?
As an example, I have this simple object I want to serialize:
@XStreamAlias(value="domain")
public class Domain
{
@XStreamAsAttribute
private String type;
private String os;
(...)
}
How do I achieve exactly the following output with XStream?
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<os>linux</os>
</domain>
XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".
Add name space to document root element as attribute. Transform the document to XML string. The purpose of this step is to make the child element in the XML string inherit parent element namespace. Now the xml string have name space.
Xml. Serialization namespace contains several Attribute classes that can be applied to members of a class. For example, if a class contains a member that will be serialized as an XML element, you can apply the XmlElementAttribute attribute to the member.
The xmlns attribute is an XML keyword for a namespace declaration.
XStream doesn't support namespaces but the StaxDriver
it uses, does. You need to set the details of your namespace into a QNameMap
and pass that into the StaxDriver
:
QNameMap qmap = new QNameMap();
qmap.setDefaultNamespace("http://libvirt.org/schemas/domain/qemu/1.0");
qmap.setDefaultPrefix("qemu");
StaxDriver staxDriver = new StaxDriver(qmap);
XStream xstream = new XStream(staxDriver);
xstream.autodetectAnnotations(true);
xstream.alias("domain", Domain.class);
Domain d = new Domain("kvm","linux");
String xml = xstream.toXML(d);
Output:
<qemu:domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<qemu:os>linux</qemu:os>
</qemu:domain>
This is a bit of a hack, but it's quick and easy: add a field to your class called xmlns
, and only have it non-null during serialisation. To continue your example:
@XStreamAlias(value="domain")
public class Domain
{
@XStreamAsAttribute
private String type;
private String os;
(...)
@XStreamAsAttribute
@XStreamAlias("xmlns:qemu")
String xmlns;
public void serialise(File path) {
XStream xstream = new XStream(new DomDriver());
xstream.processAnnotations(Domain.class);
(...)
PrintWriter out = new PrintWriter(new FileWriter(path.toFile()));
xmlns = "http://libvirt.org/schemas/domain/qemu/1.0";
xstream.toXML(this, out);
xmlns = null;
}
}
To be complete, setting xmlns = null
should be in a finally
clause. Using a PrintWriter
also allows you to insert an XML declaration at the start of the output, if you like.
Alternatively, this use case could be handled quite easily with a JAXB implementation (Metro, EclipseLink MOXy, Apache JaxMe, etc):
Domain
package com.example;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Domain
{
private String type;
private String os;
@XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
}
package-info
@XmlSchema(xmlns={
@XmlNs(
prefix="qemu",
namespaceURI="http://libvirt.org/schemas/domain/qemu/1.0")
})
package com.example;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlSchema;
Demo
package com.example;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws JAXBException {
JAXBContext jc = JAXBContext.newInstance(Domain.class);
Domain domain = new Domain();
domain.setType("kvm");
domain.setOs("linux");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(domain, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
<os>linux</os>
</domain>
For More Information
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With