2017-01-03 5 views
1

現在、XSD 1.1フレームワークを使用して、現在のスコープ要素の子要素に属性が含まれていることをテストしようとしています。 trueの場合、要素に対して1つのスキーマの検証が必要です。falseの場合、別のスキーマの検証が必要です。XSD 1.1 - 子要素に対する代替テストXpath

例XML

<!-- XML 1 --> 
<GrandParent name="Sam"> 
    <Parent name="Kevin"> 
     <Child name="Kyle" id="10" dob="1989-05-02"/> 
    </Parent> 
</GrandParent> 


<!-- XML 2 --> 
<GrandParent name="Sam"> 
    <Parent name="Kevin" id="10" dob="1975-10-11"/> 
</GrandParent> 

をxsdイムのXercesを使用して上記のXML例

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" > 

    <xs:element name="GrandParent"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element ref="Parent" /> 
      </xs:sequence> 
      <xs:attribute name="name" type="xs:string" use="required" /> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="Parent"> 
     <xs:alternative test="./Child/@id" type="ParentType1" /> 
     <xs:alternative     type="ParentType2" /> 
    </xs:element> 

    <xs:element name="Child"> 
     <xs:complexType> 
      <xs:attribute name="name" type="xs:string" use="required" /> 
      <xs:attribute name="id" type="xs:integer" use="required" /> 
      <xs:attribute name="dob" type="xs:date" use="required" /> 
     </xs:complexType> 
    </xs:element> 

    <xs:complexType name="ParentType1"> 
     <xs:sequence> 
      <xs:element ref="Child" /> 
     </xs:sequence> 
     <xs:attribute name="name" type="xs:string" use="required" /> 
    </xs:complexType> 

    <xs:complexType name="ParentType2"> 
     <xs:attribute name="name" type="xs:string" use="required" /> 
     <xs:attribute name="id" type="xs:integer" use="required" /> 
     <xs:attribute name="dob" type="xs:date" use="required" /> 
    </xs:complexType> 

</xs:schema> 

に使用XSD 1.1 1.1検証機能 XSD検証エラー

XML 1 
[Error] 1:46: cvc-complex-type.4: Attribute 'id' must appear on element 'Parent'. 
[Error] 1:46: cvc-complex-type.4: Attribute 'dob' must appear on element 'Parent'. 
[Error] 1:100: cvc-complex-type.2.1: Element 'Parent' must have no character or element information item [children], because the type's content type is empty. 

XML 2 
Validates 

Xpathは私にとっては間違っていないようですが、私は//Child/@idboolean(Child/@id)を含むいくつかのバリエーションを試しましたが、喜びはありません。属性の値が何であるかは気にせず、子要素にのみ存在します。


更新

マイケル・ケイが提供する以下の答えのおかげで、私は、スキーマの使用ではなく、選択肢のアサート書き直しました。ここで更新されたスキーマは次のとおりです。期待通り

<?xml version="1.0" encoding="utf-8" ?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:element name="GrandParent"> 
     <xs:complexType> 
      <xs:choice> 
       <xs:element ref="Parent" /> 
      </xs:choice> 
      <xs:attribute name="name" type="xs:string" use="required" /> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="Child"> 
     <xs:complexType> 
      <xs:attribute name="name" type="xs:string" use="required" /> 
      <xs:attribute name="id" type="xs:integer" use="required" /> 
      <xs:attribute name="dob" type="xs:date" use="required" /> 
     </xs:complexType> 
    </xs:element> 

    <xs:element name="Parent"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element ref="Child" minOccurs="0"/> 
      </xs:sequence> 
      <xs:attribute name="name" type="xs:string" use="required" /> 
      <xs:attribute name="id" type="xs:integer" use="optional" /> 
      <xs:attribute name="dob" type="xs:date" use="optional" /> 
      <xs:assert test="if (Child/@id) then not(@id or @dob) else (@id and @dob and not(Child))"/> 
     </xs:complexType> 
    </xs:element> 

</xs:schema> 

スキーマがはるかに優れて動作しているようです、私は次のXMLでそれをテストして合格したか失敗したすべてが

PASS <GrandParent name="Sam"><Parent name="Kevin"><Child name="Kyle" id="10" dob="1989-05-02"/></Parent></GrandParent> 
PASS <GrandParent name="Sam"><Parent name="Kevin" id="10" dob="1975-10-11"/></GrandParent> 
FAIL <GrandParent name="Sam"><Parent name="Kevin" id="10"/></GrandParent> 
FAIL <GrandParent name="Sam"><Parent name="Kevin" dob="1975-10-11"/></GrandParent> 
FAIL <GrandParent name="Sam"><Parent name="Kevin"/></GrandParent> 

答えて

2

タイプの代替で条件テスト子や子孫ではなく、問題の要素の属性にのみアクセスできます。

これは、検証される要素の浅いコピーとして構築されたデータモデルインスタンスに対してXPath式が評価されることを定義することによって行われます。浅いコピーには属性のコピーが含まれますが、子のコピーは含まれません。その結果、子にアクセスしようとしてもエラーは発生しません。falseを返すだけです。

制限の理由は、あなたがそれが無効であるかどうかを判断するために、無効なデータを見ている場合に発生する可能性のある問題を避けるためです:あなたは簡単に嘘つきのパラドックスで終わることができます。

この検証では、代替案を入力するのではなく、より一般的なアサーション機能が必要です。

+0

ああ、クイック返信ありがとう。なぜ標準がこれをサポートしていないのか、スキーマエラーのないテストで常に私がfalseを返していた理由については意味があります。 かなり長時間かかる可能性があるので、私はアサーションを避けようとしていましたが、実装を試してみると、期待したほど悪くはありませんでした。私は上記の質問に更新を掲載します。再度、感謝します ! – Mark

+0

私は親軸のチェックにも偽を持っています。同じ理由のためにこの動作ですか、それとも何かキャッチがありますか? – NicoBerrogorry

+0

はい、代替型のXPath式は、子を持たず、親のみを持たない要素のコピーに対して評価されます:属性のみ。 –

関連する問題