1

对于我正在使用的 XSD,经过验证的标记是有效的 HTML。我试图应用的规则应该能够应用于任何 HTML 元素。换句话说,我的规则与元素无关。我主要关心约束属性。

<xs:element name="div">
    <xs:complexType>
        <xs:sequence>
            <xs:any>
                    <xs:attribute name="containerColor">
                        <xs:simpleType>
                            <xs:restriction base="xs:string">
                                <xs:enumeration value="green"/>
                                <xs:enumeration value="red"/>
                                <xs:enumeration value="blue"/>
                                <xs:enumeration value="yellow"/>
                                <xs:enumeration value="grey"/>
                                <xs:enumeration value="black"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:attribute>
                    <xs:unique name="id" >
                        <xs:selector xpath="*"></xs:selector>
                        <xs:field xpath="*"></xs:field>
                    </xs:unique>
                </xs:any>
            </xs:sequence>
    </xs:complexType>
</xs:element>

我是 XSD 的新手。我确信我有一些基本的误解。

  • 在上面的例子中,我想说任何可以有(但不是必须有)一个“containerColor”属性。如果使用此属性,则必须是枚举颜色之一。

  • 此外,任何元素都可以有一个 ID,并且它应该是唯一的。

在上面的尝试中,我抱怨任何元素不是属性/唯一的有效上下文。

从选择器的角度来看,我关心将我正在构建的规则应用于所有元素的集合,而不是特定的元素。有没有办法用 XSD 实现这一点?

4

2 回答 2

1

不,您想要的内容无法使用 XSD 通配符来表述。此链接提供了一个视图,让您了解在 XSD 1.0 和XSD 1.1中允许使用 xsd:any 粒子做什么。基本上,您唯一可以嵌套的是注释。

如果你真的需要,你必须使用其他模式语言。Relax NG 是唯一一种模式语言(我知道),它可以通过使用通用名称类 <anyName> 作为 <element> 轻松完成您想要的工作。但是,它不(我相信)处理唯一性 - 您必须依赖 xsd:ID 数据类型。

至于唯一性和 Schematron,看看这个,也在 SO。如果 XSD 1.1 是一个选项,那么您至少可以替换 Schematron 部分。

于 2013-03-06T23:05:06.993 回答
1

您是否可以编写 XSD 模式来做您想做的事,取决于您想要限制多少文档,以及您在命名相关元素方面是否有任何自由。

在通常情况下,属性是与特定的复杂类型相关联的(因此间接地与特定元素相关联),因为属性很少适用于所有元素。(例如:一个名为 containerColor 的属性出现在 HTML 的 head 和 meta 元素上时是否有意义?那是什么意思?)

但是 XSD 支持顶级属性的声明。以下 XSD 架构声明了名为id且不containerColor在任何命名空间中的属性。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

  <xs:attribute name="containerColor">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value="green"/>
        <xs:enumeration value="red"/>
        <xs:enumeration value="blue"/>
        <xs:enumeration value="yellow"/>
        <xs:enumeration value="grey"/>
        <xs:enumeration value="black"/>
      </xs:restriction>
    </xs:simpleType>
  </xs:attribute>

  <xs:attribute name="id" type="xs:ID"/>

</xs:schema>

它们是顶级属性,不绑定到特定元素。因此,原则上,您可以将此模式交给 XSD 验证器,请求它扫描文档,接受它没有 XSD 声明的所有内容,并验证它有声明的所有内容。(XSD 规范将此称为“宽松验证”。)它的唯一声明是针对您的两个属性,因此它将验证它们并传递其他所有内容。效果将是您声明的属性在所有元素上都是允许的,并且无论它们出现在哪里都会得到验证。

这里的主要障碍是 XSD 没有尝试规范甚至定义验证器与外部世界之间的接口,并且不能保证声称符合规范的给定验证器将允许您通过这样的请求调用它。(好的一面是,对于许多 XSD 验证器,从文档元素开始的宽松验证是默认操作模式,有时是您可以获得的唯一一种,因此这可能适用于您使用的任何验证器。)

另一种方法是为 XHTML 制作 XSD 模式文档的本地副本,并将您的属性添加到应该能够携带它们的所有元素中。XSD 1.1 有一些结构可以使这项任务更容易。

于 2013-03-06T23:18:44.513 回答