8

状況

私は MOXy の JAXB 実装を使用して、スキーマに多くの類似した複雑な型を持つ大きな XML ドキュメントを操作しています。具体的には、次の構造を持つリスト ラッパー要素として機能する約 20 種類の型があります。

<ITEMS attr1="X" attr2="Y">
  <ITEM>...</ITEM>
  ...
  <EXTENSION/>
<ITEMS>

これらのリストラッパーのような要素のそれぞれについて、名前が変わり、含まれるリスト要素が変わります。ただし、属性 (すべてオプション) と単一の EXTENSION 要素 (これもオプション) は常に存在します。2 つのタイプの使用例を次に示します。

<ROLES visible="false">
  <ROLE type="X"/>
  <ROLE type="Y"/>
</ROLES>

<PAYMENTS visible="true">
  <PAYMENT>
    <PAYEENAME>Joe</PAYEENAME>
  </PAYMENT>
  <EXTENSION>
    <SOMETHING>Here</SOMETHING>
  </EXTENSION>
</PAYMENTS>

質問

これらの要素間で変更されるのは、名前とそれに含まれる 1 つ以上の要素だけであるため、コードの重複は避けたいと思います。これを行う最善の方法は何ですか?

考えられる解決策は 2 つしかありません。

1

ジェネリックを使用して具象クラスを作成し、変更されるコレクションで使用されるオブジェクト タイプを示します。次に、MOXy の外部 OX マッピングを使用して、クラスの個々の使用をシリアル化する方法を示します。何かのようなもの:

public class GenericContainer<T> {
    @XmlAttribute
    protected Boolean visibile;
    @XmlElement(name = "Extension")
    protected Extension extension;

    // OX Mappings done in external meta file
    protected List<T> items;
    ...
}

このオプションは気に入っていますが、クラスの OX マッピングを使用ごとに再定義することはできないようです。

2

List プロパティを持たない基本クラスを作成し、カスタム ラッパー要素ごとに具象クラスを 1 つ作成します。このソリューションは確実に機能しますが、ほぼ同一のクラスが約 20 個になることになります。

#1は可能ですか、それとも私が考えていなかったこれを処理するより良い方法はありますか?

前もって感謝します!

4

1 に答える 1

0
public class GenericContainer {

private Boolean visible;
private Object extension;
private List<Object> nodes;

@XmlAttribute
public Boolean isVisible() {
    return visible;
}

public void setVisible(Boolean visible) {
    this.visible = visible;
}

@XmlElement(name="EXTENSION")
public Object getExtension() {
    return extension;
}

public void setExtension(Object extension) {
    this.extension = extension;
}

@XmlAnyElement
public List<Object> getNodes() {
    return nodes;
}

public void setNodes(List<Object> nodes) {
    this.nodes = nodes;
}

}

XML インスタンスを読み取るには

    JAXBContext jaxbContext = JAXBContext.newInstance("jaxbtest1");
    Unmarshaller um = jaxbContext.createUnmarshaller();

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    Document doc = db.parse(new File("src/test1.xml"));
    Node node = doc.getFirstChild();

    JAXBElement<GenericContainer> jaxbE = um.unmarshal(node, GenericContainer.class);

    GenericContainer gc = jaxbE.getValue();
    Boolean vis = gc.isVisible();
    Element ext = (Element)gc.getExtension();
    for(Object o : gc.getNodes()) {
        Element listItem = (Element)o;
    }

しかし、コードの複製は本当に重要なのでしょうか? スキーマにリスト コンテナー型の共通の拡張ベースがあり、xjc を使用している場合、別個のクラスを避けるのはなぜですか? 結局のところ、JAXB の背後にある考え方は、一意の複合型ごとに値クラスを持つことです。

類似しているが異なる XML タイプを処理する汎用ロジックを作成でき、多数の Java クラスを必要としない場合は、StAX に切り替えることができます。

于 2012-07-25T04:04:43.173 に答える