1

私は常に、XMLSchema と DTD は同等であると理解していましたが、後者は複雑な関係 (継承など) をモデル化するときに使用するのがより面倒であることを理解していました。

最近、次のような構造を持つドキュメントを検証するスキーマを構築したいと考えました。

<data>
 <array>
   <int></int>
   <int></int>
 </array>
 </array>
   <float></float>
   <float></float>
 </array>
 <int><int>
 <float></float>
</data>

< data > 内の要素は任意の順序で表示でき、それぞれのカーディナリティは 0..* XMLSchema を使用し、< xs:all > を使用して複合型を定義すると、要素の順序が乱れる可能性がありますが、最大カーディナリティは 1 です。 < xs:sequence > と < xs:choice > は他の明白な候補ですが、私が望むよりも制限的です。

次に、DTD が次のようにこれを達成できるように見えることに気付きました。

<!ELEMENT data (array | float | int)*>

同等のスキーマを構築する方法はありますか、またはここで DTD を使用する必要がありますか?

4

2 に答える 2

1

要素の順序を保持している場合は、XSD を使用してのみ実行できます (したがって、xs:sequenceを使用できます)。つまり、floatは常に配列(存在する場合) の後に続き、intは常にfloat (存在する場合) の後に来るということです。それらを完全に)。

その理由は、XSD xs:all複合型が、そのコンテンツ型 (要素、他のネストされたグループ型など) の無制限属性をサポートしていないためです。あなたが述べているように、DTDやRelaxNGなど、他のより「リラックスした」スキーマを使用すると、そうすることができます。

XML ファイルに適合するサンプル XSD を次に示します。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:complexType name="arrayType">
            <xs:sequence>
                <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="int" minOccurs="0" maxOccurs="unbounded"/>
                <xs:element name="float" minOccurs="0" maxOccurs="unbounded"/>
            </xs:sequence>
    </xs:complexType>
    <xs:element name="data" type="arrayType"/>
</xs:schema>
于 2009-04-07T07:32:54.587 に答える
0

前の答えが間違っているので、これに戻ると思いました。実際、XML スキーマを使用して元の問題を解決できます。

正しいアプローチは、すべてのさまざまなオプション (int、float、配列) からの選択を含み、それぞれのカーディナリティが 0..* であるグループ要素を定義することです。

<xs:group name="dataTypesGroup">
    <xs:choice>
        <xs:element name="int" type="intType"/>
        <xs:element name="float" type="floatType"/>
        <xs:element name="array">
            <xs:complexType>
                <xs:choice>
                    <xs:element name="int" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
                    <xs:element name="float" type="xs:float" minOccurs="0" maxOccurs="unbounded"/>
                </xs:choice>
                <xs:attribute name="id" use="required"></xs:attribute>
            </xs:complexType>    
        </xs:element>
    </xs:choice>
</xs:group>

ここからは、complexType 定義でグループを参照し、グループのカーディナリティを 0..* に設定する必要があります。

<xs:element name="data" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
        <xs:group ref="dataTypesGroup" minOccurs="0" maxOccurs="unbounded"/>
    </xs:complexType>
</xs:element>

出来上がり。少し冗長ですが (特に RelaxNG の構文と比較すると)、XML スキーマのサポートがはるかに優れているという利点があります。元の問題を解決するために RelaxNG ベースのパーサーを作成しましたが、利用可能なバリデータ (JING など) は、Java などに同梱されている XML スキーマ ベースのツールを使用するよりもかなり扱いにくいものです。

于 2009-04-24T01:21:17.823 に答える