对 xsd:any 实施进一步的限制?
Enforce further constraints on xsd:any?
我有一个 XSD 1.0 序列,它定义了一组元素,其中一些元素可能是可选的,但 none 可以多次出现,并且还以 <xsd:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"/>
标记,以便用户能够在以编程方式导出符合 XML 时以最简单的方式添加自己的数据元素(即理想情况下不需要他们定义自己的 namespace/XSD)。
当处理用户生成的 XML 时,我会忽略他们通过 <any>
标签添加的任何自定义元素,但我想知道是否有办法强制元素的唯一性名称,以便我可以确定它们不会放入 maxOccurs=1
序列中定义的重复元素?
这里有一个例子xsd(互动版here):
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="testxsd" targetNamespace="testxsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="XSDSequence">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="itemA" type="xsd:string"
minOccurs="1" maxOccurs="1"/>
<xsd:element name="itemB" type="xsd:string"
minOccurs="0" maxOccurs="1"/>
<xsd:element name="itemC" type="xsd:string"
minOccurs="1" maxOccurs="1"/>
<xsd:any minOccurs="0" maxOccurs="unbounded"
namespace="##any" processContents="lax"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
这是一个示例 XML,它通过了 XSD 验证,但由于最后 <itemA>
重复,我想出错:
<XSDSequence xmlns="testxsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<itemA>foo</itemA>
<itemC>bar</itemC>
<randomElement>this is ok</randomElement>
<itemA>I want this second itemA to cause an error</itemA>
</XSDSequence>
(请注意,通过属性而不是元素捕获数据项是不是我想做的事情。)
不,在 XSD 1.0 中,一旦允许 any 元素,就不能指定超出 minOccurs
所提供的进一步限制, maxOccurs
、namespace
和 processContents
。
在XSD 1.1中,您还可以对xsd:any
元素进行xsd:assertions
;你可以用断言来表达你的约束。 [更新:不要错过 XSD 1.1 的 :xsd:any/@notQName="itemA itemB itemC"
]
也许确保元素 itemA
、itemB
和 itemC
不重复的最简单方法是使用 namespace="##other"
而不是 namespace="##any"
. (这假定命名空间 testxsd
中除这三个之外的元素不需要出现在此处。)
或移动到 XSD 1.1 并添加属性 notQName="itemA itemB itemC"
。
我有一个 XSD 1.0 序列,它定义了一组元素,其中一些元素可能是可选的,但 none 可以多次出现,并且还以 <xsd:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="lax"/>
标记,以便用户能够在以编程方式导出符合 XML 时以最简单的方式添加自己的数据元素(即理想情况下不需要他们定义自己的 namespace/XSD)。
当处理用户生成的 XML 时,我会忽略他们通过 <any>
标签添加的任何自定义元素,但我想知道是否有办法强制元素的唯一性名称,以便我可以确定它们不会放入 maxOccurs=1
序列中定义的重复元素?
这里有一个例子xsd(互动版here):
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="testxsd" targetNamespace="testxsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:element name="XSDSequence">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="itemA" type="xsd:string"
minOccurs="1" maxOccurs="1"/>
<xsd:element name="itemB" type="xsd:string"
minOccurs="0" maxOccurs="1"/>
<xsd:element name="itemC" type="xsd:string"
minOccurs="1" maxOccurs="1"/>
<xsd:any minOccurs="0" maxOccurs="unbounded"
namespace="##any" processContents="lax"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
这是一个示例 XML,它通过了 XSD 验证,但由于最后 <itemA>
重复,我想出错:
<XSDSequence xmlns="testxsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<itemA>foo</itemA>
<itemC>bar</itemC>
<randomElement>this is ok</randomElement>
<itemA>I want this second itemA to cause an error</itemA>
</XSDSequence>
(请注意,通过属性而不是元素捕获数据项是不是我想做的事情。)
不,在 XSD 1.0 中,一旦允许 any 元素,就不能指定超出 minOccurs
所提供的进一步限制, maxOccurs
、namespace
和 processContents
。
在XSD 1.1中,您还可以对xsd:any
元素进行xsd:assertions
;你可以用断言来表达你的约束。 [更新:不要错过 XSD 1.1 的 xsd:any/@notQName="itemA itemB itemC"
]
也许确保元素 itemA
、itemB
和 itemC
不重复的最简单方法是使用 namespace="##other"
而不是 namespace="##any"
. (这假定命名空间 testxsd
中除这三个之外的元素不需要出现在此处。)
或移动到 XSD 1.1 并添加属性 notQName="itemA itemB itemC"
。