1

次の XML ドキュメントがあるとします。

<root>
  <genres> 
    <genre name="comedy" />
    <genre name="academic" />
  </genres>
  <authors>
    <author name="Thomson">
      <writings>
        <writing genre="academic">The text book</writing>
        <writing genre="comedy">The worst comedy</writing>
      <writings>
    </author>
  </authors>
  <readers>
    <reader name="Phil">
      <read writenBy="Thomson">The text book</read>
    </reader>
    <reader name="John" />
  </readers>
</root>

ご覧のとおり、'reader' 要素には 'read' 子要素がない場合があります。
ただし、次のようなエントリがないことを確認する検証プロセスが必要です。

<reader name="Paul">
  <read writtenBy="Thomson">A writing the author never wrote</read>
</reader>

私ができることは、キーとキーリファレンスを使用して、以前に定義された属性に基づいて属性が取り得る値を制限することです (受け入れられた回答を参照)。これに基づいて、'writtenBy' 属性が実際に著者の名前を参照しているか、または執筆のジャンル属性が以前に定義されたジャンルに由来するかを確認できます。

XSDドキュメントに列挙をハードコーディングできることは知っています(受け入れられた回答を参照)。
また、アサーション (XSD 1.1) を使用して、XML に含まれる情報に基づいてより柔軟な列挙を行うこともできます (受け入れられた回答を参照)。
しかし、これらのアプローチはハードコードされているため、使用できません。現在属性値で行っているように、要素値に対して同様のチェックを行う方法はありますか?

4

2 に答える 2

1

あなたの要件を正しく理解していれば、key/keyref はほぼそれを処理できます。共通の祖先 (ルート) のレベルでは、次のようにキーを定義する必要があります。

* selector = authors/author/writings/writing
* fields = 
  (a) ../../@name 
  (b) .

でkeyrefを定義します

* selector = readers/reader/read
* fields =
  (a) @writtenBy
  (b) .

唯一の問題は、使用../../@nameできないことです。キーとキー参照に許可されている XPath サブセット内の先祖の属性を参照することはできません。これに対する解決策は、(a) XML 設計を変更して "writing" 要素の作成者名をコピーするか、(b) 代わりに XSD 1.1 アサーションを使用することです。

于 2013-11-13T08:11:37.660 に答える
1

いくつかの可能性があります。readまず、要素のコンテンツがwriting適切な作成者による要素のコンテンツであることを確認する key と keyref を使用して、巧妙なことを実行できる可能性があります。

readただし、各書き込みに ID を与え、要素がその ID を参照するようにする方が簡単です。冗長性を排除すると、一貫性をチェックする必要がなくなります。もちろん、表示目的で、いつでも XSLT を使用して作成者と著作の名前を取得できます。

key と keyref をこれ以上プッシュできず、XML 表現の冗長性を排除したくない場合、指定した制約を確認する最も簡単な方法は、XSD 1.1 または Schematron のいずれかでアサーションを使用することです。

これらのうち、2 番目の方法をお勧めします (XML を再構築して、有効性制約をより単純で簡単に確認できるようにします)。もちろん、あなたの好みは異なるかもしれません。

于 2013-11-13T01:54:43.337 に答える