在将对象序列化为XML时如何添加XML命名空间(xmlns)

我在XStream的帮助下将对象序列化为XML。 如何告诉XStream将xmlns插入到对象的XML输出中?

举个例子,我有这个想要序列化的简单对象:

@XStreamAlias(value="domain") public class Domain { @XStreamAsAttribute private String type; private String os; (...) } 

如何使用XStream实现以下输出?

  linux  

或者,使用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); } } 

产量

   linux  

了解更多信息

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); 

输出:

  linux  

这有点像黑客攻击,但它快速而简单:在类中添加一个名为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声明。