1

これを検索しましたが、問題の解決策が見つからないため、この質問を破棄しないでください。

XSD で記述された非常に複雑な XML 構成を持つサービスがあります。物事をスムーズに進めるためには、守らなければならないルールがたくさんあります。XSD は構成の構造を記述しますが、今やらなければならないルールは記述しません。いくつかのグローバル ルールを作成した後、さらに複雑な処理を行う必要があり、問題が発生しました。バリデーターがルート要素の key/keyref/unique のみを使用するように見えます。それを説明するために、小さな XSD および XML ファイルを作成しました。

XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://test.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://test.org/XMLSchema.xsd"
    xmlns:t="http://test.org/XMLSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Orders" type="t:OrdersList">
    <xs:key name="OrderNo">
      <xs:selector xpath="./t:Order" />
      <xs:field xpath="@Number" />
    </xs:key>
  </xs:element>

  <xs:complexType name="OrdersList">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Order" nillable="false" type="t:Order" />
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="Order">
    <xs:sequence>
      <xs:element minOccurs="1" maxOccurs="1" name="Lines" nillable="false" type="t:OrdersLinesList" />
    </xs:sequence>
    <xs:attribute name="Number" use="optional" type="xs:string" />
    <xs:attribute name="ClientId" use="optional" type="xs:int" />
  </xs:complexType>

  <xs:complexType name="OrdersLinesList">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Line" nillable="false" type="t:OrderLine">
        <!-- THE PROBLEM -->
        <xs:key name="LineNoKey">
          <xs:selector xpath="./t:Line" />
          <xs:field xpath="@LineNumber" />
        </xs:key>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="OrderLine">
    <xs:attribute name="LineNumber" use="optional" type="xs:string" />
    <xs:attribute name="ProductId" use="optional" type="xs:int" />
    <xs:attribute name="Amount" use="optional" type="xs:decimal" />
  </xs:complexType>
</xs:schema>

XML:

<?xml version="1.0" encoding="utf-8"?>
<Orders xmlns="http://test.org/XMLSchema.xsd">
  <Order Number="0001/5/13" ClientId="123">
    <Lines>
      <Line LineNumber="1" ProductId="123" Amount="4" />
      <Line LineNumber="2" ProductId="124" Amount="4" />
    </Lines>
  </Order>
  <Order Number="0002/5/13" ClientId="123">
    <Lines>
      <Line LineNumber="1" ProductId="123" Amount="4" />
      <!-- Duplicate number - it DOES validate as expected. -->
      <Line LineNumber="1" ProductId="124" Amount="4" />
    </Lines>
  </Order>
  <!-- Duplicate number - it doesn't validate as expected. -->
  <Order Number="0002/5/13" ClientId="123">
    <Lines>
      <Line LineNumber="1" ProductId="123" Amount="4" />
      <Line LineNumber="2" ProductId="124" Amount="4" />
    </Lines>
  </Order>
</Orders>

賢明な答えが見つからないいくつかの質問があります。

  1. 上記を解決する方法。LineNumber は一意である必要がありますが、Order/Lines 内のみです。
  2. keyref に存在しない仮想値を含めることを許可することはできますか (私たちのサービスはいくつかの定義済みのものを使用しています...たとえば、機能を拡張できるようにするためにカスタムのものは XML で定義されていますが、ほとんどの場合、ユーザーは定義済みのものを使用します)
  3. タグ内の要素のリスト (上記の Lines のようなもの) に、属性が特定の値に設定されたタグが少なくとも 1 つあるかどうかを判断する方法はありますか? 良い例は、一意の名前を持つテーブルのリストのように説明することです。これには、一意の名前を持つ列のリストがあり、列の少なくとも 1 つが主キーです。
4

1 に答える 1