Xsd 简单类型由属性驱动的元素的XML架构

Xsd 简单类型由属性驱动的元素的XML架构,xsd,xsd-1.1,Xsd,Xsd 1.1,我想为包含选项的文档编写一个XML模式(XSD1.1)。每个选项都有一个名称和一个类型(如布尔值、整数、字符串等)以及一个与该类型匹配的数据。类型列表是固定的,但很长。(为了简单起见,清单3中只列出了3个。) 我如何做到这一点而不重复荒谬的数量 用例1 以下是此架构的有效文档 清单1: <abc:options> <abc:option name="is-enabled" type="boolean">false</abc:option> <ab

我想为包含选项的文档编写一个XML模式(XSD1.1)。每个选项都有一个名称和一个类型(如布尔值、整数、字符串等)以及一个与该类型匹配的数据。类型列表是固定的,但很长。(为了简单起见,清单3中只列出了3个。)

我如何做到这一点而不重复荒谬的数量

用例1 以下是此架构的有效文档

清单1:

<abc:options>
  <abc:option name="is-enabled" type="boolean">false</abc:option>
  <abc:option name="wing-span"  type="float">1.2</abc:option>
</abc:options>

假的
1.2
用例2 此文档对此架构无效,因为@type属性的简单类型位错误

<abc:options>
  <abc:option name="is-enabled" type="boolean">24</abc:option>
  <abc:option name="wing-span"  type="float">this-is-not-a-number!</abc:option>
</abc:options>

24
这不是一个号码!
到目前为止我所尝试的。。。 清单3是我迄今为止的尝试。但这很糟糕,因为我必须为每个数据类型重新声明@name属性。有更好的解决办法吗?也就是说,我不必为每个可能的数据类型重新声明@name属性

清单3:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:abc="http://www.example.com"
           targetNamespace="http://www.example.com"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">

  <xs:element name="options">
    <xs:complexType>
      <xs:sequence minOccurs="1" maxOccurs="unbounded">
        <xs:element name="abc:option" type="option-Type"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name="option-Datum-Type">
    <xs:restriction base="xs:string">
      <xs:enumeration value="boolean"/>
      <xs:enumeration value="integer"/>
      <xs:enumeration value="float"/>
    </xs:restriction>
  </xs:simpleType>

  <xs:complexType name="option-Type-boolean">
    <xs:simpleContent>
      <xs:extension base="xs:boolean">
        <xs:attribute name="name" type="xs:token" use="required" />
        <xs:attribute name="type" type="abc:option-Datum-Type" use="required" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:complexType name="option-Type-string">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute name="name" type="xs:token" use="required" />
        <xs:attribute name="type" type="abc:option-Datum-Type" use="required" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:complexType name="option-Type-float">
    <xs:simpleContent>
      <xs:extension base="xs:double">
        <xs:attribute name="name" type="xs:token" use="required" />
        <xs:attribute name="type" type="abc:option-Datum-Type" use="required" />
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:complexType name="option-Type">
    <xs:alternative test="@type='boolean'"  type="abc:option-Type-boolean"/>
    <xs:alternative test="@type='string'"   type="abc:option-Type-string" />
    <xs:alternative test="@type='float'"    type="abc:option-Type-float"  />
    <xs:alternative type="xs:error"/>
  </xs:complexType>

</xs:schema>

如果类型只能是原子类型中的一种,则可以使用xs:assert如下所示:

<xs:complexType name="option-Type">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute name="name" type="xs:token" use="required" />
            <xs:attribute name="type" type="xs:string" use="required" />
            <xs:assert
                test="if (@type='boolean')  then . castable as xs:boolean
                else if (@type='float')     then . castable as xs:float
                else if (@type='int')       then . castable as xs:int
                else if (@type='string')    then . castable as xs:string
                else false()"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>
我原以为会在XPath3.0规范中添加eval/parse函数,但我认为它最终没有添加

  • 与的
    实例不同,您不能将列表(
    *
    +
    )与
    可转换为
    运算符一起使用,而只能使用
    。使用这种方法只能使用原子类型

  • 当类型声明为xs:string时,应始终成功转换为字符串


  • 一个更省钱的解决方案是将
    选项
    元素名称替换为您现在在
    选项/@name
    中拥有的名称,然后利用而不是重新发明
    xsi:type
    ,如。如果您有兴趣在这里的答案中看到这种方法的应用,请告诉我。您是否尝试过将?@Jeremythonpson Visual Studio不支持xsd 1.1,这是此结构所需的。
    <xs:assert test="eval(text() || ' castable as xs:' || @type)"/>