我有一个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>
现在假设我要定义一个 Honda 汽车类型,该类型从 CarType 扩展但是它有自己的 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 的元素(在不同的命名空间中)。这是一个示例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 元素吗?
答案 0 :(得分:7)
您可以执行与您描述的内容非常相似的操作,但在XSD中无法完全按照您的描述进行操作。复杂类型CarType的“基础”声明对数据使用者做出了许多承诺,无论是通过限制还是扩展,都必须遵守从中派生的所有类型。其中包括:
这是你正在运行的最后一项承诺。
扩展类型时,在内容模型的末尾添加新子项;对于XSD 1.0,对于对扩展有效的任何元素,总是可以从末尾删除零个或多个子元素,并生成一个对基类型有效的元素。这就是为什么你的扩展最终会有两个Fuel元素。
如果您只想要一个Fuel元素,那么您想要做的是限制而不是扩展CarType。但是您所考虑的限制并不是对基本类型的Fuel元素的法律限制。所以限制在这里对你不起作用。
当然,一种可能性是概括CarType以使其Fuel元素接受xs:string,然后将其限制两次,一次产生类似于现有CarType的东西,并且一次产生你想到的本田变体
我希望这会有所帮助。
答案 1 :(得分:-1)
我有一个类似的问题,这就是我修复的方式:
定义了一个抽象基类:java中的CarType。
为所有属性创建通常的getter / setter,除了你想为可扩展性做通用的属性:
public <T extends CarType> T getCarType() {
return (T) ref;
}
使用xsd:annotation为xsj编译器创建一个带有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设置/获取任何超类型。
我希望这会有所帮助。