4

我有一个类似于以下的文档类型:

<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 中是否有一些方法可以做到这一点?

4

2 回答 2

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) 这两个孩子是否有效。

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

于 2012-12-08T01:04:58.357 回答
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>
于 2012-12-04T07:13:09.283 回答