我正在尝试实现一些用于将java对象的内容树写回到XML文件(对象编组)的东西(我知道有很多API用于执行此操作,但是我需要它),我想让用户按照他/她想要的方式对标签进行重新排序,我知道使用JAXB可以解决的注释,但我认为使用注释可能会带来很多痛苦。如果任何人能提供任何好的方法,那将会非常有用。
由于
答案 0 :(得分:2)
注意:我是 EclipseLink JAXB (MOXy) 负责人,也是JAXB (JSR-222)专家组的成员。
在another answer中,我描述了用于指定元素顺序的标准JAXB机制。在这个答案中,我将解释如何使用MOXy的外部映射文档来解决这部分问题:
我想让用户按照他/她的需要重新排序标签,我知道 使用JAXB可以解决的注释,但我认为使用 注释可能会引起很多痛苦。
<强>根强>
在Root
类中,我使用了@XmlType
注释来指定排序。
package forum11217734;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlType(propOrder={"c", "b", "a"})
public class Root {
private String a;
private String b;
private String c;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
的 jaxb.properties 强>
要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中添加名为jaxb.properties的文件,并带有以下条目(请参阅Specifying EclipseLink MOXy as Your JAXB Provider):
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
<强>绑定acb.xml 强>
MOXy有一个外部映射文档扩展,允许您覆盖域模型上的映射(请参阅Extending JAXB - Representing Metadata as XML)。我们将使用此文档指定另一个排序。
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum11217734">
<java-types>
<java-type name="Root">
<xml-type prop-order="a c b"/>
</java-type>
</java-types>
</xml-bindings>
<强>绑定cab.xml 强>
我们可以使用其他地图文档来提供备用排序。
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="forum11217734">
<java-types>
<java-type name="Root">
<xml-type prop-order="c a b"/>
</java-type>
</java-types>
</xml-bindings>
<强>演示强>
以下演示代码演示了在创建JAXBContext
时如何利用外部映射文档。我们将以Root
三种不同的方式封送相同的实例。
package forum11217734;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
Root root = new Root();
root.setA("Foo");
root.setB("Bar");
root.setC("Baz");
// CBA
JAXBContext cbaContext = JAXBContext.newInstance(Root.class);
Marshaller cbaMarshaller = cbaContext.createMarshaller();
cbaMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
cbaMarshaller.marshal(root, System.out);
// ACB
Map<String, Object> acbProperties = new HashMap<String, Object>(1);
acbProperties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum11217734/binding-acb.xml");
JAXBContext acbContext = JAXBContext.newInstance(new Class[] {Root.class}, acbProperties);
Marshaller acbMarshaller = acbContext.createMarshaller();
acbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
acbMarshaller.marshal(root, System.out);
// CAB
Map<String, Object> cabProperties = new HashMap<String, Object>(1);
cabProperties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, "forum11217734/binding-cab.xml");
JAXBContext cabContext = JAXBContext.newInstance(new Class[] {Root.class}, cabProperties);
Marshaller cabMarshaller = cabContext.createMarshaller();
cabMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
cabMarshaller.marshal(root, System.out);
}
}
<强>输出强>
以下是运行演示代码的输出:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<c>Baz</c>
<b>Bar</b>
<a>Foo</a>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>Foo</a>
<c>Baz</c>
<b>Bar</b>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<c>Baz</c>
<a>Foo</a>
<b>Bar</b>
</root>
答案 1 :(得分:1)
JAXB (JSR-222)实现提供了几种不同的机制,用于在将内容编组到XML时指定XML元素的顺序。解组时,JAXB不要求元素按顺序排列。
选项#1 - @XmlType(propOrder = {“c”,“b”,“a”})
propOrder
注释上的@XmlType
属性允许您指定订单。
的根强> 的
package forum11217734;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlType(propOrder={"c","b", "a"})
public class Root {
private String a;
private String b;
private String c;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
的输出强> 的
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<c>Baz</c>
<b>Bar</b>
<a>Foo</a>
</root>
了解更多信息
选项#2 - @XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
您还可以使用@XmlAccessorOrder
注释指定应按字母顺序编组属性。
的根强> 的
package forum11217734;
import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
public class Root {
private String a;
private String b;
private String c;
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
}
的输出强> 的
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<a>Foo</a>
<b>Bar</b>
<c>Baz</c>
</root>
DEMO CODE
以下演示代码用于为上述每个选项生成输出。
package forum11217734;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Root.class);
Root root = new Root();
root.setA("Foo");
root.setB("Bar");
root.setC("Baz");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(root, System.out);
}
}