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 所回答的,<xs:extension
不能直接是<xs:complexType
的子代,而是必须包含在<xs:complexContent
或<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,这些确实改变了内容类型price
从 xs:string
到 xs: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 如何通过枚举限制属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在通过 SAX Xerces 解析 XML Doc 时引用 XSD Schema 位置?