質問

XJCを使用してXMLスキーマからJavaクラスを生成していますが、以下はXSDの抜粋です。

<xs:element name="NameInfo">
  <xs:complexType>
    <xs:sequence>
      <xs:choice>
        <xs:element ref="UnstructuredName"/> <!-- This line -->
        <xs:sequence>
          <xs:element ref="StructuredName"/>
          <xs:element ref="UnstructuredName" minOccurs="0"/> <!-- and this line! -->
        </xs:sequence>
      </xs:choice>
      <xs:element ref="SomethingElse" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

ほとんどの場合、生成されたクラスは問題ありませんが、上記のブロックでは次のようなものが得られます。

public List<Object> getContent() {
  if (content == null) {
    content = new ArrayList<Object>();
  }
  return this.content;
}

その上に次のコメントがあります:

* You are getting this "catch-all" property because of the following reason: 
* The field name "UnstructuredName" is used by two different parts of a schema. See: 
* line XXXX of file:FILE.xsd
* line XXXX of file:FILE.xsd
* To get rid of this property, apply a property customization to one 
* of both of the following declarations to change their names: 
* Gets the value of the content property.

問題の2行の最後にコメントを付けました。

現時点では、これはベンダー間で決定されたため、スキーマを変更するのは簡単ではないと思います。このルート(可能であれば)に進行することはかなり遅くなるため、このルートに行きたくありません。

私は検索して見つけました このページ, 、外部カスタマイズは私がやりたいことですか?私は主に生成されたクラスを使用しているので、これらのクラスを生成するプロセスに完全に精通していません。 「プロパティカスタマイズ」の簡単な例は素晴らしいでしょう!スキーマを使用できる限り、Javaクラスを生成する代替方法は問題ありません。

編集:2つを明確にする必要があります UnstructuredName 確かに同じ要素です。

役に立ちましたか?

解決

ここで重要な問題は、あなたが持っていることです <xs:sequence> から成る <xs:choice>, 、Javaで「a」に翻訳します List Javaのタイプ構造は、これをより良く表現するほど柔軟ではありません。

バインディングのカスタマイズ そうかもしれない あなたを助けてください。しかし、この場合、私はこの情報を表現するより良い方法を見ることができないので、私はそうではないと思います。

私が過去に使用していた別の手法は、最初にシンプルなXSLT変換を介してスキーマを渡し、コンポーネントをよりJAXBに優しいものに再配置しながら、ドキュメントが実際に持っている同じ構造を許可することです。これにより、オリジナルを変更せずにスキーマを「変更」できます。

他のヒント

呼ばれるバインディングカスタマイズを使用することもできます <xjc:simple />:

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
              jxb:version="2.0">
        <jxb:globalBindings>
            <xjc:simple />
        </jxb:globalBindings>
</jxb:bindings>

ただし、これはベンダー固有のものであることをお勧めします(XJC以外のものを使用しています;))

より詳しい情報 ここ

私は同じ問題を抱えています。 XMLBEANSとAXISに切り替えました。 XMLBEANSは、問題なく頭痛なしにスキーマをコンパイルできます。 Jaxbはこれを処理できません。 JaxBにこれを処理させるために、スキーマを少し変更できます。

  <xs:sequence>
          <xs:choice>
    <!-- changed the following line -->
            <xs:element name="UnstructuredTop" type="UnstructuredName"/> 
    <!-- end of change -->
            <xs:sequence>
              <xs:element ref="StructuredName"/>
              <xs:element ref="UnstructuredName" minOccurs="0"/>
            </xs:sequence>
          </xs:choice>
          <xs:element ref="SomethingElse" minOccurs="0"/>
    </xs:sequence>

その後、Jaxbは2つを区別し、ひっくり返さずに区別します。

しかし、あなたの状況は私の状況のようなものです。スキーマを変更することは問題外でした。そこで、私はXMLBEANSとAXIS(SUX)を使用しました。

問題を解決するためにラッパークラスを作成しました。

List<JAXBElement<?>> contentList = address.getContent();
if (contentList != null && contentList.size() > 0) {
    Address4JaxbMula address4JaxbMula = new Address4JaxbMula(contentList);

... }

...

public static class Address4JaxbMula {
    public CountryCodeType countryCode;
    public AddressFixType addressFix;
    public String addressFree;

    public Address4JaxbMula(List<JAXBElement<?>> contentList) {
        if (contentList != null && contentList.size() > 0) {
            for (JAXBElement<?> content : contentList) {
                Object value = content.getValue();
                if (value.getClass().isAssignableFrom(CountryCodeType.class)) {
                    countryCode = (CountryCodeType) content.getValue();
                } else if (value.getClass().isAssignableFrom(AddressFixType.class)) {
                    addressFix = (AddressFixType) content.getValue();
                } else {
                    addressFree = (String) value;
                }
            }
        }
    }

}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top