Xml Schema:基于属性值具有相同名称但不同类型的节点
我需要一个实现此目的的架构:
I need a schema that accomplished this:
<object type="possession">
<property name="VIN">1111111111111111</property>
<property name="Year">2003</property>
<property name="Make">Chevrolet</property>
</object>
- VIN"属性必须为 17 个字符
- Year 属性必须是 gYear 类型
- Make"属性必须符合 {Ford、Chevrolet、Mazda} 的枚举
现在我有这个:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="object">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="property" maxOccurs="1" minOccurs="0" type="VinType"></xs:element>
<xs:element name="property" maxOccurs="1" minOccurs="0" type="YearType"></xs:element>
<xs:element name="property" maxOccurs="1" minOccurs="0" type="MakeType"></xs:element>
</xs:choice>
<xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<!-- Vehicle Identification number (VIN) -->
<xs:simpleType name="VinRestriction">
<xs:restriction base="xs:string">
<xs:length fixed="true" value="17"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="VinType" mixed="true">
<xs:simpleContent>
<xs:extension base="VinRestriction">
<xs:attribute name="name" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="VIN" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Vehicle Year -->
<xs:simpleType name="YearRestriction">
<xs:restriction base="xs:gYear"/>
</xs:simpleType>
<xs:complexType name="YearType" mixed="true">
<xs:simpleContent>
<xs:extension base="YearRestriction">
<xs:attribute name="name" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="Year" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Vehicle Make -->
<xs:simpleType name="MakeRestriction">
<xs:restriction base="xs:string">
<xs:enumeration value="Chevrolet"/>
<xs:enumeration value="Ford"/>
<xs:enumeration value="Mazda"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="MakeType" mixed="true">
<xs:simpleContent>
<xs:extension base="MakeRestriction">
<xs:attribute name="name" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="Make" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
XSD 1.0 的一个众所周知的限制是你不能这样做:元素的类型完全由元素决定.这个问题通常被称为共现约束",如果你搜索这个词,你会发现很多参考资料.
It's a well known restriction of XSD 1.0 that you can't do this: the type of an element is determined solely by the element. The problem is often called "co-occurrence constraints" and if you search on this term you will find plenty of references.
它可以在 XSD 1.1 中使用条件类型分配"的新工具来完成.XSD 1.1 目前已在 Xerces(测试版)和 Saxon (EE 9.4) 中实现.
It can be done in XSD 1.1 using the new facility of "conditional type assignment". XSD 1.1 is currently implemented in Xerces (beta) and Saxon (EE 9.4).
解决该问题的另一种方法是使用先进行转换然后进行验证的管道进行验证.转换通常会将
更改为
Another way to tackle the problem is to do validation using a pipeline that first does a transformation, then validates. The transformation would typically change <property name="VIN">1111111111111111</property>
to <VIN>11111111111111111</VIN>