11

次の形式に従う Q&A として構造化された XML ドキュメントがあります (わかりやすくするために編集されています)。

<question>
    <answer id="1">
        <question>
            <answer id="1"/>
            <answer id="2"/>
            <answer id="3"/>
        </question>
    </answer>
    <answer id="2">
        <question>
            <answer id="1"/>
            <answer id="2"/>
        </question>
    </answer>
</question>

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

<xs:element name="question">
     <xs:complexType>
        <xs:sequence>
            <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded">
            </xs:element>
        </xs:sequence>
    </xs:complexType>
    <xs:unique name="AnswerIdUnique">
        <xs:selector xpath="./*" />
        <xs:field xpath="@id" />
    </xs:unique>
</xs:element>

<xs:complexType name="answerType">
    <xs:sequence>
        <xs:element ref="question" minOccurs="0" maxOccurs="1" />
    </xs:sequence>
    <xs:attribute name="id" type="xs:token" use="required" />
</xs:complexType>

もちろん、上で見たものよりも多くのことがありますが、これは私の問題を示しています。要素のid属性が兄弟間で一意である必要があります。answer上記で定義された XSD はid、兄弟要素間で属性の一意性を強制しますが、要素の型を区別しません。一意の制約でさまざまなセレクターとフィールドを試しましたが、機能する組み合わせが見つかりませんでした。助言がありますか?

4

1 に答える 1

15

セレクターを に変更するだけ<xs:selector xpath="answer"/>で問題ありません。.//*一般に、パフォーマンス上の理由だけであれば、 のような XPath を避けることをお勧めします。

これは、ご提供いただいた XML サンプルの XML スキーマであり、ご希望どおりに動作していると思います。

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="question" type="questionType">
        <xs:unique name="AnswerIdUnique">
            <xs:selector xpath="answer"/>
            <xs:field xpath="@id"/>
        </xs:unique>
    </xs:element>
    <xs:complexType name="questionType">
        <xs:sequence>
            <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="answerType">
        <xs:sequence>
            <xs:element ref="question" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:token" use="required"/>
    </xs:complexType>
</xs:schema>

投稿された XML は、上記で問題なく検証されます。兄弟の回答の ID を複製すると、検証エラーが発生します。たとえば、次の XML:

<question> 
    <answer id="1"> 
        <question> 
            <answer id="1"/> 
            <answer id="2"/> 
            <answer id="1"/> 
        </question> 
    </answer> 
    <answer id="1"> 
        <question> 
            <answer id="1"/> 
            <answer id="2"/> 
        </question> 
    </answer> 
</question> 

検証された場合 (QTAssistant では、同じテクノロジに基づいているため、Visual Studio のメッセージと似ているはずです)、次のエラーが表示されます。

Error occurred while loading [], line 6 position 5
There is a duplicate key sequence '1' for the 'AnswerIdUnique' key or unique identity constraint.
Error occurred while loading [], line 9 position 3
There is a duplicate key sequence '1' for the 'AnswerIdUnique' key or unique identity constraint.
Document1.xml is invalid.

以下は、投稿した XSD に対する上記の XML 検証を示す Visual Studio 2010 のスクリーンショットです。問題は誤って警告として報告されますが、それでも報告されます。

一意の制約エラーを示す VS2010

オンライン バリデーター ( http://xsdvalidation.utilities-online.info/ )を無作為に選び、投稿したのと同じ XML と XSD を検証しました。エラーは次のように報告されます。

org.xml.sax.SAXParseException: Duplicate unique value [1] declared for identity constraint of element "question".org.xml.sax.SAXParseException: Duplicate unique value [1] declared for identity constraint of element "question".

XSD のターゲット名前空間がある場合に注意する必要があります。その場合、関連するすべての名前空間のエイリアスを定義し、それらをセレクターで使用する必要があります。

更新:そして名前空間を持つXSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://localhost" xmlns="http://localhost" targetNamespace="http://localhost" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="question" type="questionType">
        <xs:unique name="AnswerIdUnique">
            <xs:selector xpath="tns:answer"/>
            <xs:field xpath="@id"/>
        </xs:unique>
    </xs:element>
    <xs:complexType name="questionType">
        <xs:sequence>
            <xs:element name="answer" type="answerType" minOccurs="2" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="answerType">
        <xs:sequence>
            <xs:element ref="question" minOccurs="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attribute name="id" type="xs:token" use="required"/>
    </xs:complexType>
</xs:schema>

プレフィックスの導入とtnsセレクターでの使用に注意してください。

于 2012-04-27T21:28:57.997 に答える