1

XSD スキーマでは、要素をドキュメントの唯一の有効なルート ノードとして宣言することはできません
それはPITAですが、私はそれについて知っています。

何年もの間、リンクされた回答で提案されていることを単純に実行します.s<simpleType><complexType>sのみを<element>定義し、グローバルレベルで定義されているのは目的のルートノードだけです。

しかし、私は現在、XSD/XSLT コード ベースの素晴らしいリファクタリングを行っています。私がやりたいことの 1 つは、特定の要素を目的の型から派生した要素のみに制限することです。これらの派生物は異なるノード名を持つことができます。

<xs:complexType name="parentType">
  <xs:sequence>
    <xs:element ref="AChild" minOccurs="1" maxOccurs="unbounded" />
  </xs:sequence>
</xs:complexType>

ここでAChildは、 を使用して他の型が派生する抽象基本型ですsubstitutionGroup

<xs:complexType name="child_base" abstract="true">
  ...
</xs:complexType>

<xs:element name="AChild" type="child_base" abstract="true" />
<xs:element name="AConcreteChild" substitutionGroup="AChild" >
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="child_base">
         ...
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

<xs:element name="AnotherPossibleConcreteChild" substitutionGroup="AChild" >
  <xs:complexType>
    <xs:complexContent>
      <xs:extension base="child_base">
         ...
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:element>

ここでの問題はsubstitutionGroup、グローバル レベルで宣言された要素に対してのみ機能することです。これでtype、グローバル レベルとして宣言された以前の internal の束ができました。これelementにより、 の可能な子が完全に制限されparentTypeますが、現在グローバルになっている子のいずれかがルート要素として提供されている場合、検証が成功することも意味します。したくない。

私が検討したオプションは次のとおりです。

  • 継承を破棄しsubstitutionGroup、考えられるすべての子を別の名前空間に移動して、<xsd:any namespace="that namespace" />. いい感じですが、追加の名前空間と定義の悪い制約は好きではありません。
  • XSD レベルの問題を無視し、XSD テンプレートを使用するコードのルート ノード名と名前空間を確認します。ここで私が気に入らなかったのは、関心の分離を壊すことでした。私の設計では、XSD ファイルは呼び出しコードのブラック ボックスであり、ノード QName にハードコーディングされた依存関係を導入したくないからです。
  • 常に 2 つの「メイン」XSD ​​スキーマが存在するという原則を導入します。1 つは通常の方法でノードを検証し (私が現在行っている検証)、もう 1 つは最も緩い形式のトップレベル ノードの定義のみを含みます。

    <xs:complexType name="parentType">
      <xs:sequence>
        <xs:any namespace="##any" processContents="skip" />
      </xs:sequence>
      <xs:anyAttribute namespace="##any" processContents="skip" />
    </xs:complexType>
    
    <xs:element name="TheRootNode" type="parentType" />
    

    そして、両方のスキーマが検証された場合にのみ、私のドキュメントは正しくなります。
    ここで私が気に入らないのは、それがベスト プラクティスにどれほど深く違反しているかわからないということです。

  • リファクタリングをやめて、以前に持っていたものを保持します (そして、可能性のあるすべての子を に手動でリストする前に<xs:choice>)。

私の質問は、複数のグローバル レベル s を宣言せずに任意の派生要素制約を機能させる他の方法はありますか<element>(そのため、唯一のルート ノード制約が再び機能するようになります)。また、リストされたオプションのいずれかを選択する方がよいと思われる場合は、回答を残してください.

4

1 に答える 1

0

トップレベルのグループを使用します。

それはあなたの最後の箇条書きのようなものですが<xs:group ref=..."/>、選択を複製する代わりに、必要になるたびにそれを参照することができます(またはおそらくあなたはそれを意味しました)。

<xs:complexType name="parentType">
  <xs:group ref="AChild" minOccurs="1" maxOccurs="unbounded" />
</xs:complexType>

<xs:group name="AChild">
  <xs:choice>
    <xs:element name="AConcreteChild" type="AConcreteChild_type" />
    <xs:element name="AnotherPossibleConcreteChild" type="AnotherPossibleConcreteChild_type" />
  </xs:choice>
</xs:group>

ところで:選択肢はxsdでグループ化されているため、これも明確です。同じ置換グループで要素宣言をスキャンする必要はありません。

于 2012-12-28T05:18:49.567 に答える