有没有办法将<xs:all>语义与<xs:any>语义结合起来?</xs:any> </xs:all>

时间:2012-12-04 03:01:34

标签: xml xsd xsd-validation

我的文档类型类似于以下内容:

<foo>
  <settings>
    <!-- Must be present; in any order -->
    <time>abc</time>
    <validRun>true</validRun>
    <!-- Tool may add whatever ones it wants -->
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
  </settings>
</foo>

以下文档在语义上与前一文档相同:

<foo>
  <settings>
    <validRun>true</validRun>
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
    <time>abc</time>
  </settings>
</foo>

但以下内容无效:

<foo>
  <settings>
    <validRun>true</validRun>
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
    <!-- Error: Required element "time" not present -->
  </settings>
</foo>

我尝试了类似以下的内容,但这不起作用,因为<xs:all>不允许包含<xs:any>

<xs:all>
  <xs:element name="time" />
  <xs:element name="validRun" />
  <xs:any />
</xs:all>

在W3C Schema中是否有一些方法可以做到这一点?

2 个答案:

答案 0 :(得分:3)

  1. 您可以使用XSD 1.1,它允许通配符显示在所有组中。

  2. 如果您的必需元素位于命名空间中,并且您可以要求生成器添加的元素不在该命名空间中,那么您可以使用可识别所需语言的选项和序列来编写内容模型(如果您真的只有两个必需的元素,它不是太难;如果你有三个或四个它变得很麻烦,如果你有五个以上你不想在没有编译器的情况下这样做)。你需要的是这样的内容模型:

    <xs:sequence>
      <xs:any namespace="##other" 
              minOccurs="0" 
              maxOccurs="unbounded"/>
      <xs:choice>
        <xs:sequence>
          <xs:element ref="time"/>
          <xs:any namespace="##other" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/>
          <xs:element ref="validRun"/>
        </xs:sequence>
        <xs:sequence>
          <xs:element ref="validRun"/>
          <xs:any namespace="##other" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/>
          <xs:element ref="time"/>
        </xs:sequence>
      </xs:choice>
      <xs:any namespace="##other" 
              minOccurs="0" 
              maxOccurs="unbounded"/>
    </xs:sequence>
    
  3. 您可以使用仅包含宽松重复通配符的内容模型声明settings,并在应用程序级别(1)检查它是否包含timevalidRun以及(2)这两个孩子是有效的。

  4. 其中,如果您可以使用XSD 1.1验证器,我认为XSD 1.1可能会产生最满意的结果。目前,Xerces J和Saxon-EE都支持XSD 1.1;大多数其他XSD工具都没有。

答案 1 :(得分:2)

我想你知道如何使用<any/>元素!!即,你不能按字面意思取<any/>元素,但你必须声明可能的元素列表..

我想这会解释<any/>的用法以及解决问题的方法!! :))

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="foo" type="foo"/>
  <xs:complexType name="foo">
    <xs:sequence>
      <xs:element name="settings" type="settings"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="settings">
      <xs:sequence>
        <xs:any minOccurs="1" maxOccurs="1"/>
        <xs:any minOccurs="1" maxOccurs="1"/>
        <xs:any minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
  </xs:complexType>
  <xs:element name="somethingNotCheckedFor" type="xs:string"/>
  <xs:element name="time" type="xs:string" />
  <xs:element name="validRun" type="xs:boolean" />
  <xs:element name="somethingNotCheckedForTWO" type="xs:string"/>
</xs:schema>

上述架构不允许任何其他元素而不是声明的元素。并且它不允许重复它们也没有限制订单!!

您可以声明所有可能的元素来代替<somethingNotCheckedFor/> !!就像我已宣布<somethingNotCheckedForTWO/>一样。

下面列出的XML示例已成功验证! :
1。

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <settings>
    <time>abc</time>
    <somethingNotCheckedForTWO>abc</somethingNotCheckedForTWO>
    <validRun>true</validRun>
  </settings>
</foo>

2

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <settings>
    <time>abc</time>
    <validRun>true</validRun>
    <somethingNotCheckedForTWO>abc</somethingNotCheckedForTWO>
  </settings>
</foo>

3

<?xml version="1.0" encoding="utf-8"?>
<foo>
  <settings>
    <somethingNotCheckedFor>abc</somethingNotCheckedFor>
    <time>abc</time>
    <validRun>true</validRun>
  </settings>
</foo>