1

我想用一些未知字段和一些必填字段验证 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 non valide trouvé à partir

4

1 回答 1

4

怎么了?您的所有 XML 数据都不是命名空间限定的。也就是说:您既没有声明也没有使用任何命名空间前缀,并且没有声明默认命名空间,因此所有名称(ordersorderrequire1require2unknowunknow1unknow2)都是不合格的。

但是您的 xs:any 通配符指定namespace="##other",这意味着它仅匹配 (a) 命名空间限定和 (b) 不在使用通配符的架构文档的目标命名空间中的元素。

一种解决方案: 如果您希望ordersetc. 不合格,则要求未知的附加元素是命名空间合格的:

<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>

或者为您的架构文档提供一个目标命名空间,并要求其他元素位于不同的命名空间中。

另一种解决方案是将通配符更改为namespace="##any"- 这将需要 XSD 1.1(否则内容模型将违反“唯一粒子归属”规则)。如果您使用 XSD 1.1,您还可以更清楚地说出您似乎想说的话,即require1require2都是必需的,并且每个都必须只出现一次,而零个或多个其他元素也可以出现。

<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>

如果您必须在 XSD 1.0中,如果您使用xs:sequence而不是,您将获得更好的验证xs:choice

<xs:element name="orders">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="order" 
        maxOccurs="unbounded" 
        minOccurs="0">
        <xs:complexType>
          <xs:sequence>
            <xs:element type="xs:string" name="require1"/>
            <xs:element type="xs:string" name="require2"/>
            <xs:any namespace="##any" 
              minOccurs="0" 
              maxOccurs="unbounded" 
              processContents="lax"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:element>

这保证了您所需的元素每个都只出现一次,并且允许其他元素。它确实要求其他元素出现在最后,而不是在所需元素之前或之间,有些人认为这是一个缺点。但除非元素序列传达信息,否则没有特别要求允许它变化。

于 2013-05-28T18:07:09.937 回答