2

我希望有一个以顶级祖先类型为条件的后代元素。是否可以在 xml 模式 1.0 中对这种关系进行建模?如果是这样,怎么做?

以下是我想要的结构/验证行为:

<a1>
  <b>
    <c>
      <d/> -- allowed if ancestor is a1
    </c>
  </b>
</a1>

<a2>
  <b>
    <c>
      <d/> -- validation error - not allowed if ancestor is not a1
    </c>
  </b>
</a2>

似乎 XSD 1.1 断言可以让我做到这一点,但我坚持使用 XML Schema 1.0。

我显然可以创建并行层次结构,并且只允许在一个中使用 d 元素,但这对于我们模式的用户来说会变得冗长和混乱。

并行层次结构可能如下所示:

<a1>
  <b1>
    <c1>
      <d/> -- allowed in c1 element
    </c1>
  </b1>
</a1>

<a2>
  <b2>
    <c2>
      <d/> -- not allowed in c2
    </c2>
  </b2>
</a2>

编辑:使用CM的提示解决上述问题的方案

<xs:element name="a1">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="b" type="b1"></xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:element name="a2">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="b" type="b2"></xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>
<xs:complexType name="b1">
    <xs:sequence>
        <xs:element name="c" type="c1"></xs:element>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="b2">
    <xs:sequence>
        <xs:element name="c" type="c2"></xs:element>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="c1">
    <xs:sequence>
        <xs:element name="d"></xs:element>
    </xs:sequence>
</xs:complexType>
<xs:complexType name="c2">
    <xs:sequence>
    </xs:sequence>
</xs:complexType>
4

1 回答 1

1

是的,这是可能的。您的并行元素层次结构(如果您在 a1 中,则为 b1 和 c1,如果您在 a2 中,则为 b2 和 c2)的后备建议已经完成了一半。您想要的本质上是相同的并行层次结构,但进一步扭曲的是,您称为 b1 和 b2 的元素都称为 b(对于 c1、c2、c 也是如此)。

关键是将名称“b”绑定到 a1 的上下文中的一种类型(称为 B1)的元素,并将其绑定到 a2 的上下文中的不同类型(B2)。然后,名称“c”在类型 B1 的上下文中绑定到一种类型 (C1),在类型 B2 的上下文中绑定到不同的类型 (C2)。在类型 C1 中,允许使用 d 个元素,而在类型 C2 中则不允许。

可以在我在开发 XSD 1.0 时写的一篇论文中找到对该技术的更完整描述。可以观察到,相同的技术可以应用于任何模式语言,其中名称/类型绑定可以是给定上下文的本地;例如,Relax NG 可以做同样的事情。

于 2013-01-15T21:30:28.777 回答