Elim的博客

用来记录一些原创性的总结


Elim

JAXB之通过XmlAccessorOrder指定元素顺序

XmlAccessorOrder是用来指定对象转换为XML时对应的XML元素的生成顺序。默认情况下,这些是无序的,虽然有时候你看到的顺序跟你的对象的属性声明顺序是一致的,但是这种顺序是不受保证的。XmlAccessorOrder的定义如下:

@Inherited @Retention(RUNTIME) @Target({PACKAGE, TYPE})
public @interface XmlAccessorOrder {
        XmlAccessOrder value() default XmlAccessOrder.UNDEFINED;
}

我们可以看到,XmlAccessorOrder定义XML的顺序时是通过XmlAccessOrder来指定的,它是一个枚举类型。默认是UNDEFINED,即没有定义顺序的,另一个选项是ALPHABETICAL,用于按照字母顺序来排序。字母A排列在字母B之前。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlRootElement
public class XmlOrder {
	private String a1;
	private String d4;
	private String b2;
	private String e5;
	private String f6;
	private String c3;
	private String g7;
	public String getA1() {
		return a1;
	}
	public void setA1(String a1) {
		this.a1 = a1;
	}
	public String getB2() {
		return b2;
	}
	public void setB2(String b2) {
		this.b2 = b2;
	}
	public String getC3() {
		return c3;
	}
	public void setC3(String c3) {
		this.c3 = c3;
	}
	public String getD4() {
		return d4;
	}
	public void setD4(String d4) {
		this.d4 = d4;
	}
	public String getE5() {
		return e5;
	}
	public void setE5(String e5) {
		this.e5 = e5;
	}
	public String getF6() {
		return f6;
	}
	public void setF6(String f6) {
		this.f6 = f6;
	}
	public String getG7() {
		return g7;
	}
	public void setG7(String g7) {
		this.g7 = g7;
	}
	
}

在上面的代码中,我们定义的一些属性的顺序不是按照字母的顺序来的,在不指定按照字母顺序排序的情况下,生成的XML将不按照字母顺序排列。在上面的代码中我们指定了生成的XML将按照字母的顺序排序,那么生成的XML就会按照对应的字母顺序排序。测试代码和结果如下:

@Test
public void test() {
	XmlOrder order = new XmlOrder();
	order.setA1("1");
	order.setB2("2");
	order.setC3("3");
	order.setD4("4");
	order.setE5("5");
	order.setF6("6");
	order.setG7("7");
	JAXB.marshal(order, System.out);
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlOrder>
    <a1>1</a1>
    <b2>2</b2>
    <c3>3</c3>
    <d4>4</d4>
    <e5>5</e5>
    <f6>6</f6>
    <g7>7</g7>
</xmlOrder>

注意这个顺序是根据对象的属性名的顺序来的,而不是根据XML元素名的顺序来的。比如我们把c3属性对应的XML元素名称通过@XmlElement(name=”ac3”)改为以字母a开头的,如果是根据XML元素的名称来生成的,那么ac3应该会在a1和b2之间。可事实却是还是在b2的后面。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorOrder(XmlAccessOrder.ALPHABETICAL)
@XmlRootElement
public static class XmlOrder {
	private String a1;
	private String d4;
	private String b2;
	private String e5;
	private String f6;
	@XmlElement(name="ac3")
	private String c3;
	private String g7;
	public String getA1() {
		return a1;
	}
	public void setA1(String a1) {
		this.a1 = a1;
	}
	public String getB2() {
		return b2;
	}
	public void setB2(String b2) {
		this.b2 = b2;
	}
	public String getC3() {
		return c3;
	}
	public void setC3(String c3) {
		this.c3 = c3;
	}
	public String getD4() {
		return d4;
	}
	public void setD4(String d4) {
		this.d4 = d4;
	}
	public String getE5() {
		return e5;
	}
	public void setE5(String e5) {
		this.e5 = e5;
	}
	public String getF6() {
		return f6;
	}
	public void setF6(String f6) {
		this.f6 = f6;
	}
	public String getG7() {
		return g7;
	}
	public void setG7(String g7) {
		this.g7 = g7;
	}
	
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xmlOrder>
    <a1>1</a1>
    <b2>2</b2>
    <ac3>3</ac3>
    <d4>4</d4>
    <e5>5</e5>
    <f6>6</f6>
    <g7>7</g7>
</xmlOrder>

如果上面的场景我们就是希望ac3排在a1和b2之间怎么办呢?这就涉及到随意指定XML元素的排列顺序了。这个会在下一篇文章介绍。 (本文由Elim写于2017年8月24日)