【问题标题】:XSD validation with any element and require element使用任何元素和需要元素进行 XSD 验证
【发布时间】:2013-05-24 14:21:55
【问题描述】:

我想用一些未知字段和一些必填字段验证 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

【问题讨论】:

    标签: xml xsd xsd-validation


    【解决方案1】:

    出了什么问题? 您的 XML 数据都不是命名空间限定的。即:您既不声明也不使用任何命名空间前缀,也没有声明默认命名空间,因此所有名称(ordersorderrequire1require2unknowunknow1、@ 987654327@) 不合格。

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

    一种解决方案:如果您希望 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>
    

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

    另一种解决方案是将通配符更改为 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>
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 2018-02-09
      • 1970-01-01
      相关资源
      最近更新 更多