我正在尝试使两个XML属性互斥。如何创建XSD架构来捕获这种场景?
我想要其中一个
<elem value="1" />
<elem ref="something else" />
但不是
<elem value="1" ref="something else" />
答案 0 :(得分:9)
您不能使用属性,但可以使用子元素...
<element name="elem">
<complexType>
<choice>
<element name="value"/>
<element name="ref"/>
</choice>
</complexType>
</element>
这样你就可以......
<elem>
<value>1</value>
</elem>
...或
<elem>
<rel>something else</rel>
</elem>
答案 1 :(得分:7)
不幸的是AFAIK你不能用XML Schema做到这一点,我自己也有同样的问题。
我看过它建议如果你需要两个:
<elem type="xxx">
<elem ref="yyy">
然后<elem>
本身应分为两种类型,因为它们显然有不同的属性......
答案 2 :(得分:5)
由于在Alnitak的回答中提及RelaxNG,这是一个解决方案 使用RelaxNG(在大多数情况下,这种语言比W3C更好 架构)。请注意elem定义中的OR(|):
start = document
document = element document {elem+}
elem = element elem {ref | value}
ref = attribute ref {text}
value = attribute value {xsd:integer}
如果我有这个XML文件:
<document>
<elem value="1" />
<elem ref="something else" />
</document>
接受了它
% rnv attributes-exclusive.rnc attributes-exclusive.xml
attributes-exclusive.xml
% xmllint --noout --relaxng attributes-exclusive.rng attributes-exclusive.xml
attributes-exclusive.xml validates
如果我添加XML文件:
<elem value="1" ref="something else" />
我得到验证错误,正如我想的那样(请注意错误消息 不是最理想的):
% rnv attributes-exclusive.rnc attributes-exclusive.xml
attributes-exclusive.xml
attributes-exclusive.xml:4:0: error: attribute ^ref not allowed
required:
after
% xmllint --noout --relaxng attributes-exclusive.rng attributes-exclusive.xml
attributes-exclusive.xml:4: element elem: Relax-NG validity error : Invalid attribute value for element elem
attributes-exclusive.xml fails to validate
答案 3 :(得分:2)
XSD有这样的抽象类型:http://www.tek-tips.com/viewthread.cfm?qid=1364846(参见tsuji发布)
基本上,你给手头的元素一个 abstract ,复杂类型并在那里定义它的公共属性,对于所有不同的用例,它们完全相同(不是你的例子需要)。
然后你创建了2个(或更多)其他复杂类型,它们扩展了我刚才提到的抽象类型。在这些新类型中,您可以在每个用例之间定义不同的属性集。这就是XSD部分。
最后,您需要将XSI type
属性添加到架构实例文档中的结果元素。因此,为了有效,元素现在必须具有一组属性或另一组属性。
不是直截了当,而是灵活的,而且我们都知道:灵活性越高,事情就越困难。
答案 4 :(得分:2)
实际上, 可以通过xs:unique或xs:key使用身份约束在XSD 1.0中定义它。您选择哪一个取决于如何处理没有这两个属性之一的元素:它们对xs有效:唯一但xs:key无效。下面的代码示例包含两种变体;确保删除其中一个,否则“stricter”xs:key优先于xs:unique,即两个属性中的一个是必需的。
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="container">
<xs:complexType>
<xs:sequence>
<xs:element name="elem" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="value" use="optional"/>
<xs:attribute name="ref" use="optional"/>
</xs:complexType>
<!-- Note: Use either xs:unique or xs:key -->
<xs:unique name="attrsExclusiveOptional">
<xs:annotation>
<xs:documentation>Ensure that @value and @ref cannot occur simultaneously.
Both may be omitted.</xs:documentation>
</xs:annotation>
<xs:selector xpath="."/>
<xs:field xpath="@value | @ref"/>
</xs:unique>
<xs:key name="attrsExclusiveRequired">
<xs:annotation>
<xs:documentation>Ensure that @value and @ref cannot occur simultaneously.
One of them is required.</xs:documentation>
</xs:annotation>
<xs:selector xpath="."/>
<xs:field xpath="@value | @ref"/>
</xs:key>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
这将验证以下XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema.xsd">
<!-- Shall pass: -->
<elem value="1" />
<elem ref="something else" />
<!-- Passes for xs:unique, fails for xs:key: -->
<elem />
<!-- Shall fail: -->
<elem value="1" ref="something else" />
</container>
答案 5 :(得分:1)
对于稍后会议的读者,请注意,可以使用“条件类型分配”或断言在XSD 1.1中解决问题。