web-dev-qa-db-ja.com

XMLスキーマキー/キー参照-それらの使用方法

短い話:XSDのキー/キー参照を使用して、要素が相互に参照できるようにする方法を知りたいです。単純なxsdとXMLを使用した例の形式が必要です。

長い話:私はID/IDREFの使用法に精通しています。これらを使用して、JAXBの要素を接続します。 XSDのkey/keyrefコンストラクトにより、要素間の参照の柔軟性が向上すると繰り返し言われました。私は OReilly XMLスキーマブック を参照しました。これは、key/keyrefの正しい定義と、それがID/IDREFに似ている(しかしより良い)方法についてすべてを教えているようで、簡単な例を示していませんその使用の。 IDをある要素の属性として定義し、IDREFを別の要素の属性として定義しているので、似ているようには見えません。ただし、キー/キーリファレンスは、参照元の共通の祖先と参照先の要素(AFAIK)で定義する必要があります...

XSDファイルを使用してJAXBバインドJava XJCでクラスを生成します

ハウツー、チュートリアル、例を検索しましたが、Googleからスクラップが返ってきました。 SOでの検索についても同様です(「google」および「+」を含む包括的検索でも))。

みんなの生活をより簡単にするために、私はそれを理解したので、すでに定義されたキー/キーリファレンスのペアでXSDを準備しました。

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="referenced">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:string" />
                </xs:complexType>
            </xs:element>
            <xs:element name="owner">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:string" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:key name="aKey">
        <xs:selector xpath="owner" />
        <xs:field xpath="@id" />
    </xs:key>
    <xs:keyref name="aKeyRef" refer="aKey">
        <xs:selector xpath="referenced" />
        <xs:field xpath="@id" />
    </xs:keyref>
</xs:element>

「所有者」要素が「参照」要素を参照しているXMLの一部はどのように見えますか?

編集: Tom Wによって提案された変更を適用し、キー要素のxpath属性を「所有者」に変更しました。 JAXB(XJC)はまだ気にしません。

ありがとうございました

26
kostja

インスタンスドキュメントには特別な構文はありません。 keyrefノードが既存のキーノードと一致することが必要なだけです。検証により、キー制約が満たされているかどうかがわかります。

コードをRE:

私は自分でキーを使って手を出し始めたばかりですが、あなたのエラーを見つけたと思います-aKeyは次のようになります:

<xs:key name="aKey">
    <xs:selector xpath="owner" />
    <xs:field xpath="@id" />
</xs:key>

さらに-これは問題です-キー制約はデフォルトの名前空間を認識しません。常に、selector xpathのすべての部分に、検索する要素の名前空間接頭辞を付ける必要があります。名前空間接頭辞がない場合-難しい場合は、追加する必要があります。これは規格の制限です。

6
Tom W

OPが検索していたものと同じものを検索しているこのスレッドを見つけました-<xs:key>要素の簡単な使用例。すべてのJAXBのものはギリシャ語で、気が散っていました。他の人が後でこのスレッドを見つけるために、OPがSOで質問した2年後のMSDNに投稿された簡単な例を次に示します。

https://msdn.Microsoft.com/en-us/library/ms256101%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

MSDNリンクが変更された場合、ブレッドクラムパスは次のとおりです。

https://msdn.Microsoft.com/library 次に、[ライブラリTOCビューに切り替え]をクリックし、ドリルダウンします。

MSDNライブラリ> .NET開発> .NET Framework 4.6および4.5>開発ガイド>データとモデリング> XML標準リファレンス> XMLスキーマ(XSD)リファレンス> XMLスキーマ要素> <xsd:key>要素

5

JAXB仕様は、キー/キー参照を明示的にカバーしていません。ただし、 EclipseLink MOXy (私は技術リーダーです)などのJAXB実装には、これに対する拡張機能があります。私たちの次の2.2リリースは、注釈を介してこの種の関係を指定する手段を提供します(例をまとめます)。以下は、現在のリリースを使用してそれを行う方法へのリンクです。

詳細については、を参照してください。

[〜#〜]更新[〜#〜]

答えに例を含めたいと思っていましたが、休暇に出る前に時間切れになりました。以下は、コンセプトを示す設計ドキュメントの例です。

5
bdoughan

JAXBは、xs:keyまたはxs:keyrefによる参照をサポートしていません。仕様では、これらの制約は検証中にチェックされる場合がありますが、データには影響しません。

ただし、代わりにxs:IDxs:IDREFを使用することでこれを実現できます(多かれ少なかれ)。概要については、 2.2.15別のXML要素の参照 および 4.3リンクを使用したデータの組み立て(ID 、IDREF) Wolfgang LaunによるJ AXBチュートリアル の。

サンプルXSDの場合、これは要素定義を次のように変更することを意味します

<xs:element name="root">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="referenced">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:ID" />
                </xs:complexType>
            </xs:element>
            <xs:element name="owner">
                <xs:complexType>
                    <xs:attribute name="id" type="xs:IDREF" />
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

xs:IDタイプの識別子は、XMLドキュメント内でグローバルに一意である必要があることに注意してください。つまり、要素が異なるタイプであっても、同じXMLファイル内の2つの異なる要素に同じIDを持つことはできません。

デフォルトでは、タイプxs:IDREFの要素または属性はJava.lang.Objectにバインドします。参照されるオブジェクトのタイプが事前にわかっている場合は、JAXBアノテーションをスキーマに追加するか、外部バインディング宣言(xjc -b bindings.xjbなど)を使用して、マッピングをカスタマイズできます。

JAXBスキーマアノテーションを使用した例(テストされていません):

<xs:element name="owner">
    <xs:complexType>
        <xs:attribute name="id" type="xs:IDREF">
            <xs:annotation>
                <xs:appinfo>
                    <jaxb:property>
                        <jaxb:baseType name=”SomeType”/>
                    </jaxb:property>
                </xs:appinfo>
            </xs:annotation>
        </xs:attribute>
    </xs:complexType>
</xs:element>

外部バインディング宣言を使用した例(テストされていません):

<jaxb:bindings node="//xs:element[@name=’owner’]//xs:attribute[@name='id']”>
    <jaxb:property>
        <jaxb:basetype name="SomeType"/>
    </jaxb:property>
</jaxb:bindings>
3
markusk

これを見てみてください key/keyref tutorial

色付きのテキストは非常に役立ちます。

3
kitsune