JavaオブジェクトのコンテンツツリーをXMLファイルに書き戻すためのもの(オブジェクトマーシャリング)を実装しようとしています(それを行うためのAPIがたくさんあることは知っていますが、私から必要です)、ユーザーに彼/彼女が望むようにタグを並べ替えます.JAXBが持っているような注釈を使用するとそれが解決する可能性があることはわかっていますが、注釈を使用すると多くの苦痛が生じる可能性があると思います. 誰かが何か良いアプローチを提供できれば、とても役に立ちます。
ありがとう
JavaオブジェクトのコンテンツツリーをXMLファイルに書き戻すためのもの(オブジェクトマーシャリング)を実装しようとしています(それを行うためのAPIがたくさんあることは知っていますが、私から必要です)、ユーザーに彼/彼女が望むようにタグを並べ替えます.JAXBが持っているような注釈を使用するとそれが解決する可能性があることはわかっていますが、注釈を使用すると多くの苦痛が生じる可能性があると思います. 誰かが何か良いアプローチを提供できれば、とても役に立ちます。
ありがとう
注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。
別の回答では、要素の順序を指定するための標準の 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というファイルを追加する必要があります(「EclipseLink MOXyをJAXBプロバイダとして指定」を参照)。
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
binding-acb.xml
MOXy には、ドメイン モデルのマッピングをオーバーライドできる外部マッピング ドキュメント拡張機能があります (Extensing 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>
binding-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
3 つの異なる方法の同じインスタンスをマーシャリングします。
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>
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>
デモコード
次のデモ コードは、上記の各オプションの出力を生成するために使用されました。
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);
}
}