【问题标题】:Using an XSD I want to be able to check that all elements of a particular group exist使用 XSD 我希望能够检查特定组的所有元素是否存在
【发布时间】:2014-07-22 09:10:48
【问题描述】:

让我用下面的例子来帮助解释。

一个有效的 XML 文档可能有:

  • 所有 group1 元素或正好 0 个元素
  • 所有 group2 元素或恰好 0 个元素
  • 所有 group1 和所有 group 2 元素,或者正好是其中的 0 个

我不确定我哪里出错了,我觉得这与组标签中的 xs:all 有关。但是,我是制作和使用 XSD 的新手,因此非常感谢任何帮助。

  <xs:element name="main">
    <xs:complexType>
       <xs:choice maxOccurs="unbounded">
        <xs:group ref="group1" />
        <xs:group ref="group2" />
      </xs:choice>
    </xs:complexType>
  </xs:element>


  <xs:group name="group1">
    <xs:all>
      <xs:element ref="a"  />
      <xs:element ref="b"  />
      <xs:element ref="c"  />
      <xs:element ref="d"  />
      <xs:element ref="e"  />
      <xs:element ref="f"  />
    </xs:all>
  </xs:group>  

  <xs:group name="group2">
    <xs:all>
      <xs:element ref="g"  />
      <xs:element ref="h"  />
      <xs:element ref="i"  />
      <xs:element ref="j"  />
    </xs:all>
  </xs:group>

【问题讨论】:

  • 您不需要 maxOccurs="1" 或 minOccurs="1" 这些是默认值。如果我大约一个小时后回家时有人没有给你打个例子,我会贴出来的。
  • 我没有忘记。老婆接我的时候带我出去。快到家。 :)
  • 你这个幸运儿,期待答案。

标签: xml xsd


【解决方案1】:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:complexType name="main">
      <xs:all>
        <xs:element minOccurs="0" name="group1">
          <xs:complexType>
            <xs:all>
              <xs:element name="a" type="xs:string" />
              <xs:element name="b" type="xs:string" />
              <xs:element name="c" type="xs:string" />
              <xs:element name="d" type="xs:string" />
              <xs:element name="e" type="xs:string" />
              <xs:element name="f" type="xs:string" />
            </xs:all>
          </xs:complexType>
        </xs:element>
        <xs:element minOccurs="0" name="group2">
          <xs:complexType>
            <xs:all>
              <xs:element name="g" type="xs:string" />
              <xs:element name="h" type="xs:string" />
              <xs:element name="i" type="xs:string" />
              <xs:element name="j" type="xs:string" />
            </xs:all>
          </xs:complexType>
        </xs:element>
      </xs:all>
    </xs:complexType>

</xs:schema>  
  • 这种技术也可以满足您的要求,但是这种技术可以让您以任意顺序列出每个组中的元素(在此示例中,它们不是组,而是复杂类型)。
  • 这种技术的缺点是现在组不是全局的,因此每次需要在整个 XML 模式中引用它们时都必须像这样输入它们。

【讨论】:

  • 这是否意味着元素 a-f 必须有一个 的父标签,并且对于 标签中的 g-j 也是如此?
  • 是的,就是这个意思。如果您使用 'ref' 来引用全局组,则不能在 'all' 标记内定义组。等等,我还有一个想法,但我不确定,所以我必须先测试一下。
  • 我的想法失败了。您必须全局定义组(模式的子级),并且不能在复杂类型中嵌套两个背靠背的“所有”组。使用 .XSD 文件,您必须有某种方式来定义组,或者使用“组”标签,或者将它们分组为另一个复杂类型的子项(示例 #2)。做任何更复杂的事情很可能涉及使用另一种称为 Schematron 的验证技术(除了 .XSD)。有趣的名字,但它是一个 ISO 标准。
  • 您可以尝试通过在使用 XSD 进行验证之前应用 XSLT 转换来重新排序原始 XML 中的元素。这将允许您使用使用组/序列的第一个示例。这是一篇关于使用 XSLT 重新排序 XML 元素的帖子。 stackoverflow.com/questions/6895948/…
  • 感谢您的帮助 Jason,我将不得不重新考虑我的方法。我可能会对此进行更多研究,或者可能使用多个模式来完成我需要做的事情。干杯。
【解决方案2】:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="a" type="xs:string" />
  <xs:element name="b" type="xs:string" />
  <xs:element name="c" type="xs:string" />
  <xs:element name="d" type="xs:string" />
  <xs:element name="e" type="xs:string" />
  <xs:element name="f" type="xs:string" />
  <xs:element name="g" type="xs:string" />
  <xs:element name="h" type="xs:string" />
  <xs:element name="i" type="xs:string" />
  <xs:element name="j" type="xs:string" />

  <xs:group name="group1">
    <xs:sequence>
      <xs:element ref="a" />
      <xs:element ref="b" />
      <xs:element ref="c" />
      <xs:element ref="d" />
      <xs:element ref="e" />
      <xs:element ref="f" />
    </xs:sequence>
  </xs:group>

  <xs:group name="group2">
    <xs:sequence>
      <xs:element ref="g" />
      <xs:element ref="h" />
      <xs:element ref="i" />
      <xs:element ref="j" />
    </xs:sequence>
  </xs:group>

    <xs:complexType name="main">
        <xs:choice maxOccurs="2">
          <xs:group ref="group1" />
          <xs:group ref="group2" />
      </xs:choice>
  </xs:complexType>

</xs:schema>

• 您在整个示例中都使用了“ref”。这意味着您正在引用全局的东西(定义为“模式”的直接子代)。我将此添加到我的示例中,因此没有对我所指的内容做出任何假设。

• 您还提到了组。如果一组元素一起出现在 XML 文档的多个位置,您可以将这些元素组合在一起,以便更容易地同时引用它们。换句话说,就像您可以创建我上面提到的全局定义的元素并在整个 XML 模式中引用它们一样,您可以命名一个模型组(序列、无序列表或选择,但不是“全部”),并且在整个 XML 模式中引用该组。同样,我在示例中添加了这些全局定义的(“模式的子”)组,这样就不会混淆我所指的“ref”。

• 默认的 minOccurs 和 maxOccurs 属性值都是 1。这些默认值分配给“choice”元素,只有一组选择中的一个元素可以出现在有效的 XML 文档中。如果 maxOccurs 属性的值大于 1,则该值决定了可能出现的选项数量。你说这两个选项都可以出现,所以我将该值设置为 2。

• 使用&lt;xs:all&gt; 的一种方法是不使用全局组,而是在每次出现时将它们简单地键入到XML Schema 中,从而允许分组元素按任何顺序排列。我在下面的第二个答案显示了如何克服这个问题。

如果我让你感到困惑,请告诉我。 哎呀...不得不修正一个小错字。现在一切都好起来了。对此感到抱歉,我试图快速解决这个问题并且搞砸了。杰森

【讨论】:

  • 谢谢杰森,我想这几乎就是我所追求的。但是我对顺序的理解是这些项目必须按照指定的顺序出现。我所追求的是每组中的元素出现一次,但可以按任何顺序出现,这就是我认为 xs:all 最合适的原因。即 group1 中元素的顺序可能是 b、d、a、c、e、f,这样就可以了。
  • 如果您可以发布一个使用 的示例,那将非常有用。我不太明白如何在 中输入它们仍然会留下 2 个已定义的“组”,您可以在其中为每个“组”拥有所有这些或没有。
猜你喜欢
  • 2019-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多