2

XSD要素があります

<xsd:element name="author" type="cmd:Author" nillable="true">
    <xsd:annotation>
        <xsd:documentation>Contains author name and author id
        </xsd:documentation>
    </xsd:annotation>
</xsd:element>

タイプの作者:

<xsd:complexType name="Author">
    <xsd:annotation>
        <xsd:documentation>Author's name and id.
        </xsd:documentation>
    </xsd:annotation>
    <xsd:simpleContent>
        <xsd:extension base="cmd:AuthorName">
             <xsd:attribute name="id" type="cmd:Id" use="optional">
                <xsd:annotation>
                    <xsd:documentation>Author's Id
                    </xsd:documentation>
                </xsd:annotation>
            </xsd:attribute>
        </xsd:extension>
    </xsd:simpleContent>
</xsd:complexType>

ベースの作成者名:

<xsd:simpleType name="AuthorName">
    <xsd:annotation>
        <xsd:documentation>Type defining author's name. 
                It may contain characters from AllowedChars
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="cmd:AllowedChars">
        <xsd:maxLength value="112"/>
    </xsd:restriction>
</xsd:simpleType>

タイプ ID:

<xsd:simpleType name="Id">
    <xsd:annotation>
        <xsd:documentation>Id
        </xsd:documentation>
    </xsd:annotation>
    <xsd:restriction base="xsd:string">
        <xsd:pattern value="\d{6}"/>
    </xsd:restriction>
</xsd:simpleType>

問題は、常に ID を持っていることですが、AuthorName が null になることがあります。

その状況で私が得るものは次のとおりです。

<author id="111111"/>

私が取得したいものは次のとおりです。

<author id="111111" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:nil="true"/>

私の実際の状態では、スキーマの互換性に問題があります。XSDモデルを変更せずにやりたいことをすることは可能ですか? Author を AuthorName と AuthorId に分割することは下位互換性がなく、かなり大きなアプリケーションを書き直す必要があります。

追加情報 (何が役に立ち、何が役に立たないのかよくわかりません): アプリケーションは J2E にあり、xsd を JAXB にバインドし、XJC を使用してクラスを生成しています。

生成されたクラスの作成者:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Author", propOrder = {
    "value"
})
public class Author implements Serializable
{
    @XmlValue
    protected String value;
    @XmlAttribute(name = "id")
    protected String id;
    //getters and setters
}
4

1 に答える 1

1

実装に関する詳細情報も提供する必要がある場合があります。ほとんどの場合、それが必要なものを手に入れるのを妨げているのです。

仕様的には、あなたは正しいです。XSD 仕様は、xsi:nil 属性が true に設定されている要素に他の XML 属性が表示される可能性があることを明確に示しています (強調は私のものです)。

xsi:nil値を持つ属性がある場合、要素はコンテンツなしで「有効」である可能性がありますtrue。そのようにラベル付けされた要素は空である必要がありますが、対応する複合型で許可されている場合は属性を持つことができます。

問題は、ほとんどのバインド テクノロジがこの動作を実装していないことです。たとえば、 MSDN のこの記事では、シナリオが標準の XML シリアライザーでサポートされていないことが明確に示されています。これは抜粋です:

  • XML ドキュメントをオブジェクトに逆シリアル化する場合: XmlSerializerクラスが xsi:nil="true" を指定する XML 要素を検出すると、対応するオブジェクトに null 参照を割り当て、他の属性を無視します。この状況は、xsi:nil="true" とともに他の属性を表示できる XML スキーマ実装によって XML ドキュメントが作成された場合に発生する可能性があります。つまり、true のnil値を null オブジェクト参照に実質的にバインドしません。

逆に、逆の場合は機能しません。つまり、他の属性が設定されている場合、xsi:nil="true" 属性をシリアル化することはできません。

社内でこれを行っている場合は、シリアライザーを調整して希望どおりに動作させる方法があるかもしれません。繰り返しますが、詳細情報を提供する必要があります。それ以外の場合は、上で示したように、(そのままでは) これが機能しないプラットフォームがあると想定する必要があります。

于 2015-12-05T00:08:44.940 に答える