我在XStream的帮助下将对象序列化为XML。 如何告诉XStream将xmlns插入到对象的XML输出中?
作为一个例子,我有这个想要序列化的简单对象:
@XStreamAlias(value="domain")
public class Domain
{
@XStreamAsAttribute
private String type;
private String os;
(...)
}
如何使用XStream实现完全以下输出?
<domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<os>linux</os>
</domain>
答案 0 :(得分:16)
XStream不支持命名空间,但它使用的是StaxDriver
。您需要将命名空间的详细信息设置为QNameMap
并将其传递到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);
输出:
<qemu:domain type="kvm" xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
<qemu:os>linux</qemu:os>
</qemu:domain>
答案 1 :(得分:5)
或者,使用JAXB实现(Metro,EclipseLink MOXy,Apache JaxMe等)可以非常轻松地处理此用例:
<强>域强>
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;
}
}
<强>包信息强>
@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;
<强>演示强>
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);
}
}
<强>输出强>
<?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>
了解更多信息
答案 2 :(得分:4)
这有点像黑客攻击,但它快速而简单:在您的类中添加一个名为xmlns
的字段,并且在序列化期间只允许它为非null。继续你的例子:
@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;
}
}
要完成,设置xmlns = null
应该在finally
子句中。如果您愿意,使用PrintWriter
还允许您在输出的开头插入XML声明。