1

2つのxsdファイルがあります。最初のファイルはcommon.xsdで、もう1つはですnode.xsd。両方node.xsdcommon.xsd同じを共有しtargetNamespaceます。using属性で定義されたをcommon.xsd参照します。ただし、またはのいずれにも含まれていません。しかし、これらのxsdファイルを使用して検証したXMLは、検証に合格します(すべてのコーナーのユースケースを試しました)。elementnode.xsdrefnode.xsdcommon.xsdincludeimport

どうしてこれが可能かしら。これは、同じ名前空間を共有しているためですか?またelement、XSDに合法的なものを含めたりインポートしたりせずに参照していますか?

編集:

簡略化されたコードスニペット(実際のxsdははるかに複雑であり、より大きな理由でこの形式で記述されています):

common.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:my="my-namespace"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        targetNamespace="my-namespace"
        elementFormDefault="qualified">
  <xsd:element name="common" type="my:commonType" />
  <xsd:complexType name="commonType">
    <xsd:choice minOccurs="0" maxOccurs="unbounded">
      <xsd:element ref="my:node"/>
      <!-- few other elements -->
    </xsd:choice>
  </xsd:complexType>
</xsd:schema>

node.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        xmlns:my="my-namespace"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        targetNamespace="my-namespace"
        elementFormDefault="qualified">
  <xsd:include schemaLocation=common.xsd"/>
  <xsd:element name="node" type="my:nodeType"
           substitutionGroup="my:common" />
  <xsd:complexType name="nodeType">
    <xsd:complexContent>
      <xsd:extension base="my:commonType">
        <!-- some 5-7 attributes -->
        <xsd:anyAttribute/>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

これらのxsdを使用すると、要素を何度でもネストできます。例えば

<my:node>
  <my:node />
  <my:node>
    <my:node />
  </my:node>
</my:node>

を含めずmy:nodeにで参照されていることを確認できます。(これがどのように機能するかについても興味があります。)common.xsdnode.xsd

4

1 に答える 1

2

これをさらに邪悪に見せることができます... in を削除しxsd:includenode.xsdも、XML を検証できます! これを行う方法については、このXerces APIをご覧ください。

仕様の観点から言えば、XML スキーマ プロセッサはさまざまな方法でスキーマの場所を解決できるという考えです。また、個別に見た場合、一部の XSD ファイルはぶら下がっている参照のために有効ではない可能性があることも意味しますが、上記のような API またはカスタム リゾルバー (たとえば、「カタログ」ファイルのサポート) を介してまとめると、結果は同等スキーマになります。有効。

XSD プロセッサが通常動作する方法は、解決できる参照を通じてロードできるすべてのスキーマ コンポーネントをまとめてから、これらのコンポーネントがどこから来たかに関係なく、全体として結果を調べることです。あなたの場合、node.xsdはcommon.xsdをもたらします。common.xsdのコンポーネントに必要なすべてのものがによってすでに取り込まれたコンポーネントの中から見つかるため、結果は有効なスキーマですnode.xsd

あなたの場合、 xsd:schema タグの内部コンテンツが in にcommon.xsd置き換わるかのxsd:includeようですnode.xsd。それを手でやれば結果は正しいですよね?

補足として、あなたが示したスニペットはcommon置換グループの使用を示していないことを指摘します。念のために言っておきますが、置換を行うには、置換グループのヘッドを参照する必要があります。

于 2012-10-08T19:04:23.520 に答える