xml - 允许元素来自一个 complexType AND/OR 另一个
问题描述
我有一个元素tag
,它的复杂类型由name
,operator
和value
;组成 其中name
是“GENRE”、“ALBUM”或“ARTIST”(简化)之一,应允许以下内容operators
:“EQ”(等于)、“CS”(包含)或“SW”(startsWith)(简化)。
现在有tag
带有name
“YEAR”的整数值,而不是所有其他字符串,因此应该只允许运算符“LT”(更少)和“GT”(更大)(简化)。
我无法将此条件构建到我现有的 XSD 中,因为不允许在一个元素中包含多个 complexType。因此,在我的 java 例程中处理它们时,我首先可以捕捉到冲突,这有点晚了。我希望 XML-Validator 尽早“喊出”格式错误的 XML。
这是我的 XSD 架构的摘录:
<xs:element name="tags" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="tag" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="name" minOccurs="1" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="PLAYLISTS" />
<xs:enumeration value="GENRE" />
<xs:enumeration value="ALBUM" />
<xs:enumeration value="ARTIST" />
<xs:enumeration value="ALBUM_ARTIST" />
<xs:enumeration value="YEAR" />
<xs:enumeration value="TITLE" />
<xs:enumeration value="COMMENT" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="operator" minOccurs="1" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="EQ" />
<xs:enumeration value="CS" />
<xs:enumeration value="SW" />
<xs:enumeration value="EW" />
<xs:enumeration value="LT" />
<xs:enumeration value="GT" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element type="xs:string" name="value" minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
这是一个 XML 的示例摘录,其中前两个标签元素应该是有效的,最后一个应该是无效的。因为整数运算符分别用于字符串值,所以字符串运算符用于整数值。
<tags>
<tag>
<name>ALBUM</name>
<operator>CS</operator>
<value>The</value>
</tag>
<tag>
<name>YEAR</name>
<operator>LT</operator>
<value>2010</value>
</tag>
<tag>
<name>ALBUM</name>
<operator>GT</operator>
<value>The</value>
</tag>
<tag>
<name>YEAR</name>
<operator>CS</operator>
<value>2010</value>
</tag>
</tags>
我希望您可以理解我的问题,并且您可以帮助我找到合适的解决方案-提前致谢!
解决方案
你应该知道你只能用XSD-1.1来实现这个,因为xs:assert
需要这个功能。因此,要使用具有 value 的子元素来限制您的tag
元素,您必须在定义的相应元素之后设置此限制:name
YEAR
</xs:sequence>
<tag>
<xs:assert test="name!='YEAR' or (name='YEAR' and value castable as xs:integer and (operator='LT' or operator='GT'))" />
此断言将您的<tag>
元素限制为那些<name>
子元素的值不为“YEAR”的元素,以及那些子元素<name>
的值为“YEAR”且<value>
类型xs:integer
为<operator>
“LT”或“GT”的子元素. 在这种情况下要小心 AND/OR,因为断言需要对所有 <tag>
s 为 TRUE,因此or
.
您的完整 XSD 文件可能如下所示:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.1">
<xs:element name="tags">
<xs:complexType>
<xs:sequence>
<xs:element name="tag" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="name" minOccurs="1" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="PLAYLISTS" />
<xs:enumeration value="GENRE" />
<xs:enumeration value="ALBUM" />
<xs:enumeration value="ARTIST" />
<xs:enumeration value="ALBUM_ARTIST" />
<xs:enumeration value="YEAR" />
<xs:enumeration value="TITLE" />
<xs:enumeration value="COMMENT" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="operator" minOccurs="1" maxOccurs="1">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="EQ" />
<xs:enumeration value="CS" />
<xs:enumeration value="SW" />
<xs:enumeration value="EW" />
<xs:enumeration value="LT" />
<xs:enumeration value="GT" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element type="xs:string" name="value" minOccurs="1" maxOccurs="1" />
</xs:sequence>
<xs:assert test="name!='YEAR' or (name='YEAR' and value castable as xs:integer and (operator='LT' or operator='GT'))" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
另一种限制<tag>
元素的方法是
<xs:assert test="(name!='YEAR' and (operator!='LT' or operator!='GT')) or (name='YEAR' and value castable as xs:integer and (operator='LT' or operator='GT'))" />
它还从除 之外的所有元素中排除运算符LT
和。GT
YEAR
推荐阅读
- jquery - 是否可以重构此功能?
- c# - Dynamics CRM:CreateRequest 并发问题
- php - 使用自动生成的 ID 将教义插入 Oracle 12c 数据库表
- c# - 如何在 C#(Windows 窗体应用程序)中以数组的形式获取文件的详细信息?
- c - c中的md5sum数组
- python - 来自选定列表框项目的可滚动复选按钮
- php - PHP Magic __invoke 对类的对象属性
- angular - Angular4+ ReactiveForms 禁用和启用控件
- c++ - 在 C++20 中是否不再允许在 std 中为程序定义类型专门化函数模板?
- jenkins - 我们如何使用 ibmcloud 在 jenkins 中创建 bluemix 的 cloudant 服务?ibmcloud 插件可用于 jenkins