XML Schema 如何通过枚举限制属性

Posted

技术标签:

【中文标题】XML Schema 如何通过枚举限制属性【英文标题】:XML Schema How to Restrict Attribute by Enumeration 【发布时间】:2012-02-14 02:11:48 【问题描述】:

我有以下 XML 标记

<price currency="euros">20000.00</price>

如何将货币属性限制为以下之一:

欧元 磅 美元

价格要翻倍?

当我尝试在两者上输入一个类型时,我只是得到一个错误,这是我目前所得到的:

<xs:element name="price">
    <xs:complexType>
        <xs:attribute name="currency">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="pounds" />
                    <xs:enumeration value="euros" />
                    <xs:enumeration value="dollars" />
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
</xs:element>

【问题讨论】:

如果您这样做,您还需要从 元素中删除 type="xs:string" 。当 simpleType 或 complexType 存在时,你不能给出类型。 【参考方案1】:

您的价格定义中似乎缺少数值。 请尝试以下操作:

<xs:simpleType name="curr">
  <xs:restriction base="xs:string">
    <xs:enumeration value="pounds" />
    <xs:enumeration value="euros" />
    <xs:enumeration value="dollars" />
  </xs:restriction>
</xs:simpleType>



<xs:element name="price">
        <xs:complexType>
            <xs:extension base="xs:decimal">
              <xs:attribute name="currency" type="curr"/>
            </xs:extension>
        </xs:complexType>
</xs:element>

【讨论】:

正如@kjhughes 所回答的,&lt;xs:extension 不能直接是&lt;xs:complexType 的子代,而是必须包含在&lt;xs:complexContent&lt;xs:simpleContent 中。【参考方案2】:

旧问题的新答案

这个老问题的现有答案都没有解决真正的问题。

真正的问题xs:complexType 不能直接将xs:extension 作为 XSD 中的子级。解决方法是首先使用xs:simpleContent。详情如下...


您的 XML,

<price currency="euros">20000.00</price>

将针对以下更正的 XSD 中的 任一 有效:

本地定义的属性类型

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="price">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:decimal">
          <xs:attribute name="currency">
            <xs:simpleType>
              <xs:restriction base="xs:string">
                <xs:enumeration value="pounds" />
                <xs:enumeration value="euros" />
                <xs:enumeration value="dollars" />
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

全局定义的属性类型

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:simpleType name="currencyType">
    <xs:restriction base="xs:string">
      <xs:enumeration value="pounds" />
      <xs:enumeration value="euros" />
      <xs:enumeration value="dollars" />
    </xs:restriction>
  </xs:simpleType>

  <xs:element name="price">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="xs:decimal">
          <xs:attribute name="currency" type="currencyType"/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

注意事项

作为commented by @Paul,这些确实改变了内容类型 pricexs:stringxs:decimal,但这并不严格 必要的,并不是真正的问题。 作为answered by @user998692,您可以分离出 货币的定义,你可以改为xs:decimal,但是 这也不是真正的问题。

真正的问题xs:complexType 不能直接将xs:extension 作为XSD 中的孩子;首先需要xs:simpleContent

一个相关的问题(没有被问到但可能混淆了其他答案):

price 有一个属性怎么可能被限制?

在这种情况下,需要对priceType 进行单独的全局定义;仅使用本地类型定义是不可能做到这一点的。

当元素有属性时如何限制元素内容

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:simpleType name="priceType">  
    <xs:restriction base="xs:decimal">  
      <xs:minInclusive value="0.00"/>  
      <xs:maxInclusive value="99999.99"/>  
    </xs:restriction>  
  </xs:simpleType>

  <xs:element name="price">
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base="priceType">
          <xs:attribute name="currency">
            <xs:simpleType>
              <xs:restriction base="xs:string">
                <xs:enumeration value="pounds" />
                <xs:enumeration value="euros" />
                <xs:enumeration value="dollars" />
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

【讨论】:

【参考方案3】:

你需要创建一个类型并设置该类型的属性:

<xs:simpleType name="curr">
  <xs:restriction base="xs:string">
    <xs:enumeration value="pounds" />
    <xs:enumeration value="euros" />
    <xs:enumeration value="dollars" />
  </xs:restriction>
</xs:simpleType>

然后:

<xs:complexType>
    <xs:attribute name="currency" type="curr"/>
</xs:complexType>

【讨论】:

您好,遗憾的是,这不允许我同时将价格类型限制为“双倍”以及“货币”属性的限制枚举

以上是关于XML Schema 如何通过枚举限制属性的主要内容,如果未能解决你的问题,请参考以下文章

XML Schema:具有仅包含文本的属性的元素?

如何在通过 SAX Xerces 解析 XML Doc 时引用 XSD Schema 位置?

advanced-day17-XML,DTD约束,schema约束及枚举,注解

基于枚举的 JSON Schema 切换对象属性

如何通过传入枚举值和属性类型来获取枚举的自定义属性?

如何限制Objective C中枚举值的可见性?