3

私のアプリケーションは Web サービスを呼び出しており、maven-jaxb2-plugin を使用して WSDL/XSD から Java クラスを生成しました。Web サービスの呼び出しはしばらくの間問題なく機能していましたが、最近、オブジェクトを XML にマーシャリングする際に問題が発生しました。

[org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'ns1:TheFooAndBarThing'. 
No child element '{"http://www.myschemanamespace.xyz/v1":BarId}' is expected at this point.]

XSD 部分は次のようになります。

<xs:complexType name="TheFooAndBarThing">
    <xs:sequence>
        <xs:element name="FooId" minOccurs="1" maxOccurs="1" type="nx:FooIdType"/>
        <xs:element name="BarId" minOccurs="1" maxOccurs="100" type="nx:BarIdType"/>
    </xs:sequence>
</xs:complexType>

生成されたクラスTheFooAndBarThingは次のようになります (Javadoc は削除されています)。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TheFooAndBarThing", propOrder = {
    "fooId",
    "barId"
})
public class TheFooAndBarThing {

    @XmlElement(name = "FooId", required = true)
    protected String fooId;
    @XmlElement(name = "BarId", required = true)
    protected List<String> barId;

    public String getFooId() {
        return fooId;
    }

    public void setFooId(String value) {
        this.fooId = value;
    }

    public List<String> getBarId() {
        if (barId == null) {
            barId = new ArrayList<String>();
        }
        return this.barId;
    }

}

本当の問題を見つけるには、時間とコーヒーが必要でした。私の間違いは、リストに 100 を超えるBarId要素を入れたことです。

では、私の質問は次のとおりです
。XSD から maxOccurs/minOccurs 値を Java コードに取得して、要素のリストを作成するときに最大値/最小値として使用するにはどうすればよいですか?

4

2 に答える 2

3

簡単な答え: 簡単な方法はありません。

スキーマ派生クラスには、元のスキーマへの参照がなくなりました。XSOM などを使用して元のスキーマを解析したとしても、対応する XML スキーマ構造を見つけてチェックすることはできません。

この問題に対処する最善の方法は、カスタムXJC プラグインを作成することです (かなりの数のプラグインを作成しました)。

XJC がスキーマをコンパイルすると、最初にモデルが作成され、次にいわゆるアウトライン (事前レンダリングされたコード) が作成され、コードがレンダリングされます。モデルには元の XML スキーマ構造に関する情報がまだ含まれているため、関連するすべての min/maxOccurs 情報を見つけることができます。

問題は、スキーマ コンストラクトとスキーマ派生クラスのプロパティとの間のマッピングが常に 1:1 であるとは限らないことです。場合によっては、複数の要素が 1 つのプロパティにマップされることがあります。膨大な数の例外と特殊なケースがあります。ただし、単純なケースでは機能させることができます。とにかく、仕事は簡単ではありません。

于 2014-03-19T20:20:51.790 に答える
1

JAXB-Facetsを試すことができます。

minoccursmaxoccursに特定の値を設定する例を次に示します。

@MinOccurs(value = 0)
@MaxOccurs(value = 100)
private List<String> test;
于 2015-08-07T09:16:34.287 に答える