6

車の基本フィールドを定義する xml スキーマがあります。

<xs:simpleType name="FuelType">
    <xs:restriction base="xs:string">
        <xs:enumeration value="Regular Unleaded"/>
        <xs:enumeration value="High Octane"/>
        <xs:enumeration value="Leaded"/>
    </xs:restriction>
</xs:simpleType>
<xs:complexType name="CarType">
    <xs:sequence>
        <xs:element name="Make" type="xs:string"/>
        <xs:element name="Model" type="xs:string"/>
        <xs:element name="Cylinders" type="xs:int"/>
        <xs:element name="Fuel" type="FuelType"/>
    </xs:sequence>
</xs:complexType>

ここで、 CarTypeから拡張されたHondaの車のタイプを定義したいとしますが、 Fuelには独自の定義があります。

<xs:simpleType name="HondaFuelType">
    <xs:restriction base="xs:string">
        <xs:enumeration value="85"/>
        <xs:enumeration value="87"/>
        <xs:enumeration value="89"/>
        <xs:enumeration value="91"/>
        <xs:enumeration value="93"/>
        <xs:enumeration value="95"/>
    </xs:restriction>
</xs:simpleType>
<xs:complexType name="HondaCarType">
    <xs:complexContent>
        <xs:extension base="car:CarType">
            <xs:sequence>
                <xs:element name="Fuel" type="HondaFuelType"/>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>

CarTypeを拡張すると、必要なものがすべて得られますが、スキーマでは、(異なる名前空間で) Fuelという名前の 2 つの要素を使用できるようになりました。サンプルの Xml インスタンスを次に示します。

<HondaCar xmlns="HondaNS" xmlns:car="CarNS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="HondaNS D:\Development\Temp\honda.xsd">
    <car:Make/>
    <car:Model/>
    <car:Cylinders>4</car:Cylinders>
    <car:Fuel>High Octane</car:Fuel>
    <Fuel>87</Fuel>
</HondaCar>

これは完全に有効な Xml ですが、(少なくとも私にとっては) 論理的に意味がありません。私の意図は、基本タイプを拡張してから*Fuel* をオーバーライドして、 HondaFuelTypeで定義された値のみを許可することでした。

拡張型のベースのFuel要素をオーバーライドまたはマスクする方法はありますか?

4

2 に答える 2

8

説明したことと非常によく似たことができますが、XSD では説明したことを正確に行うことはできません。複合型 CarType の 'base' 宣言は、データ コンシューマーに対して多くのコミットメントを行います。これは、制限または拡張によって派生したすべてのタイプが従う必要があります。これらの中には次のものがあります。

  • CarType のインスタンスには、Make、Model、Cylinders、および Fuel という名前の子があり、型が示されています。
  • Make 要素と Model 要素の値は文字列になります。
  • Cylinders 要素の値は xs:int になります。
  • Fuel 要素の値は、一連の文字列 {"Regular Unleaded", "Leaded", "High Octane"} から取得されます。

これは、あなたが最初の問題を抱えているこれらのコミットメントの最後のものです。

型を拡張すると、そのコンテンツ モデルの最後に新しい子が追加されます。XSD 1.0 では、拡張機能に対して有効な任意の要素について、最後から 0 個以上の子を削除して、基本型に対して有効な要素を生成することが常に可能です。これが、拡張機能が 2 つの Fuel 要素で終わる理由です。

Fuel 要素が 1 つだけ必要な場合は、CarType を拡張するのではなく、制限する必要があります。しかし、あなたが念頭に置いている制限は、基本タイプの燃料要素の法的な制限ではありません。したがって、ここでも制限は機能しません。

もちろん、1 つの可能性は CarType を一般化して、Fuel 要素が xs:string を受け入れるようにし、2 回制限することです。

これが役立つことを願っています。

于 2013-01-18T03:54:14.850 に答える
-1

私は同様の問題を抱えていましたが、これが私が修正した方法です:

Java で抽象基本クラス CarType を定義しました。

拡張性のために汎用化したいプロパティを除くすべてのプロパティに対して、通常のゲッター/セッターを作成します。

public <T extends CarType> T getCarType() {
    return (T) ref;
}

xsj コンパイラが適切な評価を使用できるように、xsd:annotation を使用して Java 型の xsd 要素を作成します。

<xsd:complexType name="carType">
    <xsd:annotation>
        <xsd:appinfo>
            <jaxb:class ref="com.yourclass.model.CarType"/>
        </xsd:appinfo>
    </xsd:annotation>
</xsd:complexType>

以前に行っていたように、これを他のすべての xsd 要素の拡張ベースとして使用します。これにより、CarType の任意のスーパー タイプを設定/取得できるようになります。

これが役立つことを願っています。

于 2013-02-12T21:00:14.087 に答える