我想用一些未知字段和一些必填字段来验证xml,但我不知道如何做到这一点。我尝试使用xs:any
元素,但它不起作用。
<orders>
<order>
<require1>**</require1>
<require2>**</require2>
<unknow>***</unknow>
</order>
<order>
<require1>**</require1>
<require2>**</require2>
<unknow1>***</unknow1>
<unknow2>***</unknow2>
</order>
...
我的XSD是:
<xs:element name="orders">
<xs:complexType>
<xs:sequence>
<xs:element name="order"
maxOccurs="unbounded"
minOccurs="0">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="2">
<xs:any namespace="##other"
minOccurs="0"
maxOccurs="unbounded"
processContents="lax"/>
<xs:element type="xs:string" name="require1"/>
<xs:element type="xs:string" name="require2"/>
...
但它不起作用: cvc-complex-type.2.4.a:Contenu nonvalidetrouvéàpartir
答案 0 :(得分:3)
出了什么问题?您的XML数据都不是名称空间限定的。也就是说:既没有声明也没有使用任何名称空间前缀,并且没有声明默认名称空间,所以所有名称(orders
,order
,require1
,require2
,{ {1}},unknow
,unknow1
)不合格。
但是你的xs:任何通配符指定unknow2
,这意味着它只匹配(a)命名空间限定的元素和(b)不在使用通配符的模式文档的目标命名空间中。< / p>
一个解决方案:如果您希望namespace="##other"
等不合格,请要求未知的其他元素是名称空间限定的:
orders
或者为您的架构文档提供目标命名空间,并要求其他元素位于不同的命名空间中。
另一种解决方案是将通配符更改为<orders xmlns:other="http://example.com/other">
<order>
<require1>**</require1>
<require2>**</require2>
<other:unknow>***</other:unknow>
</order>
<order>
<require1>**</require1>
<require2>**</require2>
<other:unknow1>***</other:unknow1>
<other:unknow2>***</other:unknow2>
</order>
</orders>
- 这将需要XSD 1.1(否则内容模型将违反“唯一粒子归因”规则)。如果您使用XSD 1.1,您也可以更清楚地说出您想要说的内容,即namespace="##any"
和require1
都是必需的,每个必须恰好出现一次,而零个或多个其他元素可以也出现了。
require2
如果您必须使用XSD 1.0 ,如果您使用<xs:complexType>
<xs:all>
<xs:any namespace="##any"
minOccurs="0"
maxOccurs="unbounded"
processContents="lax"/>
<xs:element type="xs:string" name="require1"/>
<xs:element type="xs:string" name="require2"/>
</xs:all>
</xs:complexType>
而非xs:sequence
,则会获得更好的验证:
xs:choice
这可以保证您所需的元素每次只出现一次,并且允许其他元素。它确实要求其他元素在最后而不是在所需元素之前或之间,有些人认为这是一个缺点。但除非元素序列传达信息,否则没有特别要求允许它变化。