如何在 XML 模式中实现互斥属性?
我试图使两个 XML 属性互斥。 如何创建 XSD 模式来捕获这种场景?
我想要其中之一
<elem value="1" />
<elem ref="something else" />
,但没有
<elem value="1" ref="something else" />
I'm trying to make two XML attributes to be mutually exclusive. How can one create an XSD schema to capture this kind of scenario?
I would like to have one of these
<elem value="1" />
<elem ref="something else" />
but not
<elem value="1" ref="something else" />
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您不能使用属性,但可以使用子元素...
这样您就可以拥有...
或...
You can't do with attributes, but you can with child elements...
This way you can have...
or...
不幸的是,据我所知,您无法使用 XML Schema 做到这一点,我自己也遇到了同样的问题。
我看到它建议,如果您需要两者:
那么
本身应该分为两种类型,因为它们显然具有不同的属性......Unfortunately AFAIK you can't do that with XML Schema, I've had the same problem myself.
I've seen it suggested that if you need both of:
then
<elem>
itself should be split into two types, since they've clearly got different attributes...由于 Alnitak 的回答中提到了 RelaxNG ,这里有一个解决方案
使用 RelaxNG(一种在大多数情况下比 W3C 更好的语言)
架构)。 请注意 elem 定义中的 OR (|):
如果我有此 XML 文件:
它被 rnv 接受 和 xmlint:
如果我在 XML 文件中添加:
我会收到验证错误,如我所愿(请注意错误信息
是次优的):
Since RelaxNG was mentioned in Alnitak's answer, here is a solution
with RelaxNG (a language which is, in most cases, better than W3C
Schema). Do note the OR (|) in the definition of elem:
If I have this XML file:
It is accepted by rnv and xmlint:
If I add in the XML file:
I get validation errors, as I want (do note that the error messages
are suboptimal):
实际上,可以通过 xs:unique 或 xs:key 使用身份约束在 XSD 1.0 中定义这一点。 您选择哪一个取决于如何处理没有这两个属性之一的元素:它们对于 xs:unique 有效,但对于 xs:key 无效。 下面的代码示例包含这两种变体; 确保删除其中之一,否则“更严格”的 xs:key 优先于 xs:unique,即需要两个属性之一。
这将验证以下 XML 文件:
Actually, it is possible to define this in XSD 1.0 using identity constraints via xs:unique or xs:key. Which one you choose depends on how elements without either of the two attributes shall be treated: They're valid with xs:unique but invalid with xs:key. The code sample below contains both variants; make sure to remove one of them, otherwise the "stricter" xs:key takes precedence over xs:unique, i.e., one of the two attributes is required.
This validates the following XML file:
XSD 为此具有抽象类型: http://www.tek-tips.com/ viewthread.cfm?qid=1364846 (参见 tsuji 的帖子)
基本上,您为手头的元素提供一个抽象、复杂类型,并在其中定义它的公共属性,即 对于所有不同的用例完全相同(您的示例不需要)。
然后,您创建 2 个(或更多)附加复杂类型,它们扩展了我刚才提到的抽象类型。 在这些新类型中,您可以定义每个用例之间不同的属性集。 这就是 XSD 部分。
最后,您需要将 XSI
type
属性添加到架构实例文档中的结果元素。 因此,为了有效,该元素现在必须具有一组属性或另一组属性。不是直接的,而是灵活的,众所周知:越灵活,事情就会变得越困难。
XSD has abstract types for this: http://www.tek-tips.com/viewthread.cfm?qid=1364846 (see post by tsuji)
Basically, you give the element at hand an abstract, complex type and define it's common attributes in there, which are exactly the same for all different use cases (not needed for your example).
Then you create 2 (or more) additional complex types which extend the abstract type I've just mentioned. Within these new types you define the differing sets of attributes between each use case. That's it for the XSD part.
Finally, you need to add a XSI
type
attribute to the resulting element in the schema instance document. So to be valid, the element must now have either one set of attributes or the other.Not straight-forward, but flexible, and as we all know: the more flexible, the more difficult something becomes.
对于稍后阅读此内容的读者,请注意,该问题可以在 XSD 1.1 中使用“条件类型赋值”或断言来解决。
For readers coming to this later, note that the problem can be solved in XSD 1.1 using either "conditional type assignment" or assertions.