Xml架构:具有相同名称但基于属性值的不同类型的节点

时间:2013-01-29 21:12:01

标签: xml schema

我需要一个完成此任务的模式:

<object type="possession">
  <property name="VIN">1111111111111111</property>
  <property name="Year">2003</property>
  <property name="Make">Chevrolet</property>
</object>
  • “VIN”属性必须为17个字符
  • “年份属性必须为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>

1 个答案:

答案 0 :(得分:3)

众所周知,XSD 1.0的限制是你无法做到这一点:元素的类型仅由元素决定。这个问题通常被称为“共现约束”,如果你搜索这个术语,你会发现很多参考文献。

可以使用“条件类型分配”的新功能在XSD 1.1中完成。 XSD 1.1目前在Xerces(beta)和Saxon(EE 9.4)中实现。

解决此问题的另一种方法是使用首先进行转换的管道进行验证,然后进行验证。转换通常会将<property name="VIN">1111111111111111</property>更改为<VIN>11111111111111111</VIN>