是否可以限制 XSD 属性遵循数字顺序?
Is it possible to restrict XSD attributes to follow a numerical order?
例如,如果我有以下 XML 文档:
<course name="math">
<grade attempt="1">F</grade>
<grade attempt="2">F</grade>
<grade attempt="3">B</grade>
</course>
我如何使用 XSD 验证属性 "attempt" 仅在存在 1 时才具有值 2,在存在 2 时才具有值 3,并且等等?
编辑:为了更清楚,我需要的是让第一个元素在属性中具有值“1”的可能性,并且每个连续的兄弟都具有该值增加一
是的,这是可能的,但在 XSD 1.0 中不行。
最简单的解决方案: 完全删除 @attempt
属性;它什么也没加。
我建议您重新审视明确强制执行约束的目标,如果隐含的话,该约束将免费提供。删除 @attempt
属性,它仅用于标识序列中 grade
元素的位置,并让序列暗示如果没有先前位置已经存在,则以后的序列位置不能存在。
XSD 1.0 无法以其原始形式帮助处理您的请求,使用 XSD 1.1 断言或 Schematron 或外部代码是多余的。只需删除 @attempt
即可轻松使用 XSD 1.0,应用程序开发也将得到简化。您可以根据序列位置在需要的任何地方生成尝试编号。
您已经提出了两个可能要强制执行的限制条件:
(a) "follow a numerical order"。我会读到它是说在每个元素上,@attempt 的值必须大于(不一定大于一个)之前的@attempt。例如 1,2,4 是合法的,但 1,4,2 不是。
(b) "only has a value of 2 if there is a 1 present"。我会读到这组尝试值形成了一个密集的数字序列,不一定是有序的。例如序列 3,1,2 是可以接受的,但 4,1,2 是不可接受的。
这是哪个?如果您对约束的描述含糊不清,我们无法帮助您编写约束。
无论哪种方式,一旦我们知道约束的真正含义,就可以很容易地使用 XSD 1.1 断言来描述约束。
更新
您说的规则是@attempt 值应严格为 1、2、3 等。在这种情况下,合适的断言可能是
every $g in grade satisfies $g/@attempt eq count($g/preceding-sibling::grade)+1]
例如,如果我有以下 XML 文档:
<course name="math">
<grade attempt="1">F</grade>
<grade attempt="2">F</grade>
<grade attempt="3">B</grade>
</course>
我如何使用 XSD 验证属性 "attempt" 仅在存在 1 时才具有值 2,在存在 2 时才具有值 3,并且等等?
编辑:为了更清楚,我需要的是让第一个元素在属性中具有值“1”的可能性,并且每个连续的兄弟都具有该值增加一
是的,这是可能的,但在 XSD 1.0 中不行。
最简单的解决方案: 完全删除 @attempt
属性;它什么也没加。
我建议您重新审视明确强制执行约束的目标,如果隐含的话,该约束将免费提供。删除 @attempt
属性,它仅用于标识序列中 grade
元素的位置,并让序列暗示如果没有先前位置已经存在,则以后的序列位置不能存在。
XSD 1.0 无法以其原始形式帮助处理您的请求,使用 XSD 1.1 断言或 Schematron 或外部代码是多余的。只需删除 @attempt
即可轻松使用 XSD 1.0,应用程序开发也将得到简化。您可以根据序列位置在需要的任何地方生成尝试编号。
您已经提出了两个可能要强制执行的限制条件:
(a) "follow a numerical order"。我会读到它是说在每个元素上,@attempt 的值必须大于(不一定大于一个)之前的@attempt。例如 1,2,4 是合法的,但 1,4,2 不是。
(b) "only has a value of 2 if there is a 1 present"。我会读到这组尝试值形成了一个密集的数字序列,不一定是有序的。例如序列 3,1,2 是可以接受的,但 4,1,2 是不可接受的。
这是哪个?如果您对约束的描述含糊不清,我们无法帮助您编写约束。
无论哪种方式,一旦我们知道约束的真正含义,就可以很容易地使用 XSD 1.1 断言来描述约束。
更新
您说的规则是@attempt 值应严格为 1、2、3 等。在这种情况下,合适的断言可能是
every $g in grade satisfies $g/@attempt eq count($g/preceding-sibling::grade)+1]