XML 模式:了解结构

详解XML中的模式Schema XML中拥有Schema特性,能够比DTD更加强大地引入元素结构,下面我们就来详解XML中的模式Schema的概念及作用和用法,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 文档定义模型为XML文档提供了规范,DTD的引入虽然解决了XML文档的规范化问题,但它文件格式类型和XML文件格式类型不一致,同时DTD提供的数据类型有限有时候无法满足... 阅读详情

XML 模式:了解结构

了解如何使用 XML 模式结构声明、扩展和限制 XML 的结构。

本系列中的其他文章:
XML 模式:了解命名空间
XML 模式:了解数据类型

 

语法定义语言的结构和语义、实施约束以及确保实例(实际数据)的有效性。正如英语(或任何其他语言)具有关联的语法来定义有关特殊句子的撰写规则,或者在给定英语句子的情况下,利用语法来检查该句的有效性一样,XML 实例文档的语法也定义相应的规则以确保该文档的结构和内容的有效性。

W3C XML 模式定义 (WXS) 采用 XML 语言表示 W3C XML 模式 (WXS) 的抽象数据模型。通过定义模式的抽象数据模型,W3C 模式并不知道用于表示该模型的语言。XML 表示形式是 WXS 指定的正式表示形式,但您可以根据所需的任何方式表示抽象数据模型并将它用于验证。例如,您可以使用任何符合抽象数据模型的数据结构直接创建内存中的模式。这将促使开发 W3C 模式验证程序的供应商提供一个可用于直接创建内存中模式的 API。

验证 XML 实例文档的语法有多种。某些语法很快便过时,而其他语法(如 DTD,它是 W3C XML 1.0 REC 的一部分)则已经通过了时间的考验。在现有语法中,XML 模式在 XML 开发人员中应用最广,这是因为:

  1. 它使用 XML 语言来定义模式。
  2. 它具有 44 个以上的内置数据类型,可以对其中的每一个数据类型进行进一步地优化,以对 XML 中的字符数据进行细粒度验证。
  3. 可以使用 minOccurs 和 maxOccurs 属性以细粒度方式定义元素的基数。
  4. 它通过 extension、restriction、import、include 和 redefine 结构支持模块化和可重用性。
  5. 它支持标识约束,以确保 XML 文档中的值在指定集中的唯一性。
  6. 它具有抽象数据模型,因此它的表示形式并不限于 XML。

以下是一个有关如何根据外部指定的模式来验证 XML 实例的示例:

import java.io.FileInputStream;
import oracle.xml.parser.v2.XMLError;
import oracle.xml.parser.schema.XML Schema;
import oracle.xml.parser.schema.XSDBuilder;
import oracle.xml.schemavalidator.XSDValidator;
...
//加载 XML 模式
XSDBuilder schemaBuilder = new XSDBuilder();
XML Schema schema = schemaBuilder.build(new FileInputStream("myschema.xsd"), null);

//将加载的 XML 模式设置为 XSDValidator
XSDValidator validator = new XSDValidator();
validator.setSchema(schema);

//针对提供的 XML 模式验证 XML 实例。
validator.validate(new FileInputStream("data.xml"));

//检查错误
XMLError error = validator.getError();
if (error.getNumMessages() > 0) {
System.out.println("XML-instance is invalid.");
error.flushErrors();
}
else {
System.out.println("XML-instance is valid.");
}
当然,XML 模式也有限制:
  1. 它不支持基于规则的验证。一个基于规则的验证示例为:如果属性“score”的值大于 80,则 XML 实例中必须存在元素“distinction”,否则元素不存在。
  2. 唯一粒子属性 (UPA) 约束过分严格地定义了用于所有类型的 XML 文档的语法。(有关更多信息,请参阅“UPA 约束”。)

在我的前几篇文章中,我介绍了命名空间的概念(在您深入研究 XML 模式之前必须了解它)、XML 模式中支持的数据类型以及用于进一步限制和使用这些数据类型的 simpleType 结构。

在本文中,我将介绍用于声明、扩展和限制 XML 结构的模式。您还将学习由 XML 模式提供的模型组、粒子以及其他约束。

Oracle XML 开发人员工具包 (XDK) 包含一个符合 W3C 标准的 XML 模式处理器以及多个实用工具,如利用 API 通过编程来创建并限制模式数据类型、分析和验证 XML 模式结构本身以及遍历 XML 模式的抽象数据模型的实用工具。请检查 oracle.xml.parser.schema 和 oracle.xml.schemavalidator 程序包。

内容和模型

元素内容

在 XML 文档中,元素内容是指包含在它的 <头> 和 </尾> 标记之间的内容。元素只能有四种类型的内容:TextOnly(纯文本)、ElementOnly(纯元素)、Mixed(混合)和 Empty(空)。在元素上声明的属性并不视为是元素内容的一部分。它们只是其声明所在的元素的一部分,他们组成了 XML 的结构。

TextOnly

如果元素在其 <头> 和 </尾> 标记之间只有字符数据(或简单称为文本数据),即如果元素没有子元素,则该元素的内容被视为是 TextOnly(纯文本)。例如:

<TextOnly>some character data</TextOnly>
ElementOnly

 

如果元素在其 <opening> 和 </closing> 标记之间只有子元素(可以选择性地由空格、制表符、换行符、回车符分隔),则该元素的内容被视为是 TextOnly(纯元素)。这些空格被称作是可忽略的空格,并通常用于对 XML 进行缩进。因此,以下内容:

没有空格的 ElementOnly 内容

<ElementOnly><child1 .../><child2 .../></ElementOnly>
等价于:

 

有空格的 ElementOnly 内容

<ElementOnly>
<child1 .../>
<child2 .../>
</ElementOnly>
混合

 

如果元素的字符数据与子元素分散在 <头> 和 </尾巴> 标记之间,则该元素的内容被视为是 Mixed(混合)。(换言之,它的内容同时包含字符数据和子元素。)混合内容后,前面所说的可忽略空格将不再是可忽略的。因此,以下内容:

<Mixed><child1.../>some character data<child1.../></Mixed>
不同于:
<Mixed>
<child1 .../>
some character data
<child1 .../>
</Mixed>
空

 

如果元素在 <头> 和 </尾> 标记之间绝对没有任何内容(甚至是空格),则该元素的内容被视为是 Empty(空)。例如:

<Empty></Empty>
另一种便于使用,并且格式清晰的元素(具有空内容)表示方法是使用单个 Empty 标记,如下所示:
<Empty />
内容模型

 

在 XML 语法中,您可以声明元素的内容模型,以指定相应 XML 实例文档中的元素内容类型。因此,内容模型是元素内容的定义。

下图演示了如何在 XML 模式中声明内容模型。沿着图中从 <schema> 开始的路径深入探讨,以了解如何声明四种元素内容(包含和不包含属性声明)的内容模型。让我们简单介绍一下每个元素内容。

图 1
图 1:在 XML 模式中声明内容模型

 

TextOnly

在以上图示中,沿路径找到 simpleType-1 以使用 TextOnly 内容模型声明元素:

<xsd:element name="TextOnly">
<xsd:simpleType>
<xsd:restriction base="xsd:string" />
</xsd:simpleType>  
</xsd:element>

或等价于

<xsd:element name="TextOnly" type="xsd:string" />
以上模式使用 TextOnly 内容模型声明了一个名为“TextOnly”(可以为任何名称)的元素,其内容 必须 是相应 XML 实例中的整数。如果元素的内容模型为 TextOnly,则它始终有一个关联的 simpleType,用于指示该元素的数据类型。例如,在本示例中,元素 TextOnly 的数据类型为 string。 请参阅上一部分中此模式的相应 XML 实例。

 

正如前面指出的,属性并不是元素内容;因此,另一个具有 TextOnly 内容并具有属性的 XML 实例的示例为:

<TextOnly att="val">some character data</TextOnly>
现在,沿着图 1 中的路径找到 simpleContent-3 ,以使用 TextOnly 内容模型和属性声明一个元素:
<xsd:element name="TextOnly">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="att" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
以上模式使用 TextOnly 内容模型声明一个名为“TextOnly”的元素,其内容必须为字符串并且在相应的 XML 实例中必须有一个名为“attr”的属性。

 

ElementOnly

沿着图 1 中的路径直到找到 sequence-5、choice-6 之一或 all-7,以使用 ElementOnly 内容模型声明一个元素:

<xsd:element name="ElementOnly">
<xsd:complexType>
<xsd:sequence> <!-- could have used choice or all instead —>
<xsd:element name="child1" type="xsd:string" />
<xsd:element name="child2" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
以上模式使用 ElementOnly 内容模型声明一个名为“ElementOnly”的元素。元素“ElementOnly”在相应的 XML 实例文档中必须具有子元素“child1”和“child2”。请参阅上一部分中此模式的相应 XML 实例。

 

另一个包含 ElementOnly 元素内容和属性的 XML 实例如下所示:

<ElementOnly att="val">
<child1 .../>
<child2 .../>
</ElementOnly>
要使用 ElementOnly 内容模型和属性声明一个元素,图 1 中的路径与声明 ElementOnly 内容模型的路径相同。然后,按如下所示在 complexType 中声明属性:
<xsd:element name="ElementOnly">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="child1" type="xsd:string" />
<xsd:element name="child2" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="att" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
以上模式的相应 XML 实例如下
<Mixed att="val">
<child1 .../>
some character data
<child1 .../>
</Mixed>
混合型

 

没着图 1 中的路径找到 sequence-5、choice-6 之一或 all-7,以使用 Mixed 内容模型(它与声明 ElementOnly 内容模型相同)声明元素,但这次将 complexType 的 mixed 属性设置为 true,如下所示:

<xsd:element name="Mixed">
<xsd:complexType mixed="true">
<xsd:sequence>
<xsd:element name="child1" type="xsd:string" />
<xsd:element name="child2" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="att" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
Empty

 

沿着此路径直到找到 complexType-2 以使用 Empty 声明一个具有或没有属性的元素:

<xsd:element name="EmptyContentModels">
<xsd:complexType>
<xsd:sequence>

<xsd:element name="Empty1">
<xsd:complexType />
</xsd:element>

<xsd:element name="Empty2">
<xsd:complexType>
<xsd:attribute name="att" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>

</xsd:sequence>
</xsd:complexType>
</xsd:element>
以上模式的相应 XML 实例如下
<EmptyContentModels>
<Empty1 />
<Empty2 att="val" />
</EmptyContentModels>
模型组

 

如果将元素的内容模型声明为 ElementOnly或混合型(意味着该元素具有子元素),则可以使用模型组更详细地指定子元素的顺序和出现位置。模型组由粒子组成;粒子可以是元素声明或其他模型组。模型组本身有一个基数,可以使用 minOccurs 和 maxOccurs 属性对其进行优化。这些特征使模型组非常强大。

XML 模式支持的三个模型组分别为:

  • Sequence - (a , b)* - 在 sequence 模型组中声明的子元素必须以模式中定义的同样顺序出现在相应的 XML 实例中。Sequence 模型组的基数范围从 0 到无限大。通过递归方式,sequence 模型组还可以进一步包含 Sequence 或 choice 模型组。
  • Choice - (a | b)* - 表示在 choice 模型组中声明的子元素集中,必须有一个元素出现在相应的 XML 实例中。Choice 模型组的基数范围从 0 到无限大。通过递归方式, choice 模型组可以进一步包含 Sequence 或 Choice 模型组。
  • all - {a , b}?- 表示在 all 模型组中声明的整个子元素集必须出现在相应的 XML 实例中,但与 sequence 模型组不同的是,顺序并不重要。因此,子元素可以任何顺序出现。all 模型组的基数只能为 0 或 1。all 模型组只能包含元素声明而不能包含任何其他模型组。

这些模型组既可以内联方式声明,也可以全局声明(一个包含名称并可重用的 <schema> 结构的直接子项)方式声明。必须在 <group> 结构中声明全局模型组,您可以以后按其名称引用它。但与内联模型组不同的是,不能在全局声明的模型组上声明 minOccurs/maxOccurs 属性。如果需要,可以在引用全局声明的模型组时使用 minOccurs/maxOccurs 属性。例如:

<xsd:group name="globalDecl">
<xsd:sequence>
<xsd:element name="child1" type="xsd:string" />
<xsd:element name="child2" type="xsd:string" />
</xsd:sequence>
</xsd:group>
随后,可以在需要时使用 group 结构以及 minOccurs/maxOccurs 属性引用全局声明的模型组:
<xsd:group ref="globalDecl" maxOccurs="unbounded">
为更好地了解模型组,以下提供了一个复杂示例:
((a | b)* , c+)?

<xsd:element name="complexModelGroup">
<xsd:complexType>

<xsd:sequence minOccurs="0" maxOccurs="1">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="a" type="xsd:string" />
<xsd:element name="b" type="xsd:string" />
</xsd:choice>
<xsd:element name="c" type="xsd:string" minOccurs="1" maxOccurs="unbounded">
</xsd:sequence>

</xsd:complexType>
</xsd:element>
complexType 叙述

 

您现在拥有足够的信息来编写一个简单的 XML 文档模式。但 XML 模式中的许多高级概念仍有待介绍。

complexType 是 XML 模式中其他强大的结构之一。您除了可以声明所有四个包含或不包含属性的内容模型以外,还可以通过继承已经声明的 complexType 以派生出新的 complexType。因此,派生的 complexType 既可以将更多声明添加到由基础 complexType 继承而来的声明(使用 extension),也可以限制基础 complexType 中的声明(使用 restriction)。

可以使用 simpleContent 或 complexContent 扩展或限制 complexType。具有 simpleContent 的 complexType 声明一个包含或不包含属性的 TextOnly 内容模型。具有 complexContent 的 complexType 可用于声明其它三个包含或不包含属性的内容模型(ElementOnly、Mixed 或 Empty)。

扩展 complexType

simpleContent

图 2
图 2:只能通过扩展具有 simpleContent 的 complexType 才能添加属性。

 

具有 simpleContent 的 complexType 可以扩展 simpleType 或具有 simpleContent 的 complexType。如图 2 中所示,在派生的 complexType 中,允许您执行的唯一操作是添加属性。例如:

<?xml version="1.0"?>
<xsd:schema targetNamespace="http://inheritance-ext-res"
xmlns:tns="http://inheritance-ext-res"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">
    
<xsd:complexType name="DerivedType1">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="att1" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="DerivedType2">
<xsd:simpleContent>
<xsd:extension base="tns:DerivedType1">
<xsd:attribute name="att2" type="xsd:string" use="required" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

<xsd:element name="SCExtension">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Derived1" type="tns:DerivedType1" />
<xsd:element name="Derived2" type="tns:DerivedType2" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
在以上模式中:

 

 

  1. DerivedType1 基于内置的 simpleType string 扩展,并添加了一个属性 attr1。
  2. DerivedType2 继承基础 DerivedType1(它是一个具有 simpleContent 的 complexType)中的属性 attr1,并添加一个属性 attr2。

 

对应于以上模式的 XML 实例如下:

<SCExtension xmlns="http://inheritance-ext-res"
xmlns:xsi="http://www.w3.org/2001/XML Schema-instance"
xsi:schemaLocation="http://inheritance-ext-res CTSCExt.xsd">

<Derived1 att1="val">abc</Derived1>
<Derived2 att1="val" att2="val">def</Derived2>
  
</SCExtension>
complexContent

 

图 3
图 3:具有 complexContent 的 complexType 可用于扩展模型组以及添加属性。

 

具有 complexContent 的 complexType 可以扩展 complexType 或具有 complexContent 的 complexType。如图 3 所示,在派生的 complexType 中,允许您添加属性以及扩展模型组。例如:

<?xml version="1.0"?>
<xsd:schema targetNamespace="http://inheritance-ext-res"
xmlns:tns="http://inheritance-ext-res"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">

<!— (child1)+ —>
<xsd:complexType name="BaseType">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="child1" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="att1" type="xsd:string" use="required" />
</xsd:complexType>

<!— ((child1)+ , (child2 | child3)) —>
<xsd:complexType name="DerivedType">
<xsd:complexContent>
<xsd:extension base="tns:BaseType">
<xsd:choice>
<xsd:element name="child2" type="xsd:string" />
<xsd:element name="child3" type="xsd:string" />
</xsd:choice>
<xsd:attribute name="att2" type="xsd:string" use="required" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

<xsd:element name="CCExtension">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Base" type="tns:BaseType" />
<xsd:element name="Derived" type="tns:DerivedType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
在以上模式中:

 

 

  1. DerivedType 继承基础 complexType 中的 sequence 模型组,并添加一个 choice 模型组,从而生成派生的 complexType 的最终内容模型- ((child1)+ , (child2 | child3))。
  2. DerivedType 继承 BaseType 中的属性 attr1,并添加属性 attr2。

对应于以上模式的 XML 实例如下:

<CCExtension xmlns="http://inheritance-ext-res"
xmlns:xsi="http://www.w3.org/2001/XML Schema-instance"
xsi:schemaLocation="http://inheritance-ext-res CTCCExt.xsd">

<Base att1="val">
<child1>This is base</child1>
<child1>This is base</child1>
</Base>
  
<Derived att1="val" att2="val">
<child1>This is inherited from base</child1>
<child1>This is inherited from base</child1>
<child1>This is inherited from base</child1>
<child3>This is added in the derived</child3>
</Derived>

</CCExtension>
限制 complexType

 

simpleContent

图 4
图 4:具有 simpleContent 的 complexType 可用于限制数据类型和属性。

 

具有 simpleContent 的 complexType 只能限制具有 simpleContent 的 complexType。如图 4 中所示,在派生的 complexType 中,可以限制基类的 simpleType,以及限制基类中的属性的类型和使用(可选、强制等)。例如:

<?xml version="1.0"?>
<xsd:schema targetNamespace="http://inheritance-ext-res"
xmlns:tns="http://inheritance-ext-res"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">
    
<xsd:complexType name="BaseType">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="att1" type="xsd:string" use="optional" />
<xsd:attribute name="att2" type="xsd:integer" use="optional" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>

<xsd:complexType name="DerivedType">
<xsd:simpleContent>
<xsd:restriction base="tns:BaseType">
<xsd:maxLength value="35" />
<xsd:attribute name="att1" use="prohibited" />

<xsd:attribute name="att2" use="required">
<xsd:simpleType>
<xsd:restriction base="xsd:integer">
<xsd:totalDigits value="2" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>

</xsd:restriction>
</xsd:simpleContent>
</xsd:complexType>

<xsd:element name="SCRestriction">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Base" type="tns:BaseType" />
<xsd:element name="Derived" type="tns:DerivedType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
在以上模式中:

 

 

  1. 您将基类的 simpleType 内容(字符串类型)限制为派生的 simpleType 中一个长度为 35 的字符串。
  2. 您禁止从基类中继承属性 att1。
  3. 您将属性 att2 的类型限制为一个 2 位整数,并使其从可选变为强制。

 

对应于以上模式的 XML 实例如下:

<SCRestriction xmlns="http://inheritance-ext-res"
xmlns:xsi="http://www.w3.org/2001/XML Schema-instance"
xsi:schemaLocation="http://inheritance-ext-res CTSCRes.xsd">

<Base att1="val">This is base type</Base>
<Derived att2="12">This is restricted in the derived</Derived>
  
</SCRestriction>
complexContent

 

图 5
图 5:具有 complexContent 的 complexType 可用于限制模型组和属性。

 

具有 complexContent 的 complexType 可以限制 complexType 或具有 complexContent 的 complexType。如图 5 中所示,在派生的 complexType 中,您必须重复基类中的整个内容模型并在需要时按照要求对其进行限制。可以按照限制 simpleContent 的同一方法来限制属性。例如:

<?xml version="1.0"?>
<xsd:schema targetNamespace="http://inheritance-ext-res"
xmlns:tns="http://inheritance-ext-res"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">

<xsd:complexType name="BaseType">
<xsd:sequence>
<xsd:element name="child1" type="xsd:string" maxOccurs="unbounded" />
<xsd:element name="child2" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="att1" type="xsd:string" use="optional" />
</xsd:complexType>

<xsd:complexType name="DerivedType">
<xsd:complexContent>
<xsd:restriction base="tns:BaseType">
<xsd:sequence>
<xsd:element name="child1" type="xsd:string" maxOccurs="4" />

<xsd:element name="child2">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="35" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>

</xsd:sequence>
<xsd:attribute name="att1" type="xsd:string" use="prohibited" />
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>

<xsd:element name="CCRestriction">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Base" type="tns:BaseType" />
<xsd:element name="Derived" type="tns:DerivedType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
在以上模式中:

 

 

  1. 您将 DerivedType(从 BaseType 继承)中的 child1 的基数从无限大限制为 4。
  2. 您将 DerivedType(从 BaseType 继承)中的 child2 的类型限制为一个长度为 35 的字符串。
  3. 您禁止从 BaseType 继承属性 att1。

 

对应于以上模式的 XML 实例如下:

<CCRestriction xmlns="http://inheritance-ext-res"
xmlns:xsi="http://www.w3.org/2001/XML Schema-instance"
xsi:schemaLocation="http://inheritance-ext-res CTCCRes.xsd">

<Base att1="val">
<child1>This is base type</child1>
<child2>This is base type</child2>
</Base>
  
<Derived>
<child1>This is restricted in the derived</child1>
<child2>This is restricted in the derived</child2>
</Derived>
  
</CCRestriction>
组装模式

 

导入、包含和 可变式效果

许多 Java 项目都涉及多个不同的类和程序包,而不只是一个大的 Java 文件,这是因为模块化可以方便代码的重用、读取和维护。随后,必须将必需的导入语句加入到类中,然后才能使用它们。同样,在 XML 模式中,您必须在各种不同命名空间中管理不同的模式,并需要将必需的导入语句加入到模式中,然后才能使用它们。

可以使用 <import/> 和 <include/> 模式结构组装 XML 模式,当然,以下应是该模式中位于其他任何声明之前的第一个语句:

<schema>
<import namespace="foo" schemaLocation="bar.xsd" />
<include schemaLocation="baz.xsd" />
  ...
</schema>
当导入的模式具有 targetNamespace 时,将使用 <import />,而当包含的模式未声明 targetNamespace 时,将使用 <include />。

 

下面,我们将介绍一个示例,该示例涉及两个模式 A 和 B,且 A 引用 B 中声明的项目。

情况 I
如果两个模式都有 targetNamespace,且模式 A 的 targetNamespace (tnsA) 不同于模式 B 的 targetNamespace (tnsB),则 A 必须导入 B。

<import namespace="tnsB" schemaLocation="B.xsd">
但 A 导入 B 时和 A 包含 B 时不指定命名空间是一个错误。

 

情况 II
如果两个模式都包含 targetNamespace,且模式 A 的 targetNamespace (tnsAB) 与模式 B 的 targetNamespace (tnsAB) 相同,则 A 必须包含 B。

<include schemaLocation="B.xsd">
A 导入 B 是错误的。

 

情况 III
如果模式 A 和 B 都没有 targetNamespace。这种情况下,A 必须包含 B。

<include schemaLocation="B.xsd" />
情况 IV
如果模式 A 没有 targetNamespace,而模式 B 包含 targetNamespace (tnsB),则 A 必须导入 B。
<import namespace="tnsB" schemaLocation="B.xsd" />
A 包含 B 是错误的,这是因为 B 包含一个 targetNamespace。

 

情况 V
如果模式 A 包含 targetNamespace (tnsA),而模式 B 不包含 targetNamespace,情况又将如何?A 应包含 B。但如果我认为在本例中,A 应导入 B,情况将如何?实际上,在这种情况下,A 可以导入或包含 B,且这两个操作都是合法的,但效果并不相同。

如果 A 包含 B,则所包含的来自 B 的所有项目将获取 A 的命名空间。这样的包含被称作 可变式 包含。

如果您不希望发生这样的可变式效果,则必须在不指定命名空间情况下完成导入。没有 namespace 属性的导入允许对不包含目标命名空间的组件进行非限定性引用。

<import schemaLocation="B.xsd">
多次导入或包含一个模式不会产生错误,这是因为模式处理器可以检测这种情况并不再加载已加载的模式。因此,A.xsd 导入 B.xsd 和 C.xsd 并不产生错误;B.xsd 和 C.xsd 各自单独导入 A.xsd。循环引用不会产生错误,但强烈建议您不要使用它。

 

顺便说明的是,一个类似 <import /> 的简单导入也是合法的。该方法只允许对不包含目标命名空间的外部组件进行非限定性引用,而不提供任何有关其所在位置的信息提示。模式处理器将利用某种机制提示出错或查找未知项目,因模式处理器而异。但使用 <include /> 是非法的。

经验法则:

 

  1. <include/> - 它的作用与在包含模式中以内联方式定义被包含的模式相当。
  2. <import/> -如果被导入的模式与导入模式的 targetNamespace 不同则始终使用 <import/>。

 

重新定义模式

您可能并不总想用其原始格式组装模式。例如,您可能需要修改从模式中导入的组件。在此类情况下,当我们需要重定义声明而不更改其名称时,我们使用重定义组件完成这一过程,要重定义的模式必须满足以下限制条件:(a) 与 重定义模式文档具有相同的 targetNamespace,(b) 根本没有 targetNamespace,这种情况下,被重定义模式文档将转变为重定义模式文档的 targetNamespace。

例如:

 

actual.xsd
<?xml version="1.0"?>
<xsd:schema targetNamespace="http://inheritance-ext-res"
xmlns:tns="http://inheritance-ext-res"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">

<xsd:complexType name="BaseType">
<xsd:sequence>
<xsd:element name="child1" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="att1" type="xsd:string" use="required" />
</xsd:complexType>

<xsd:complexType name="DerivedType">
<xsd:complexContent>
<xsd:extension base="tns:BaseType">
<xsd:choice>
<xsd:element name="child2" type="xsd:string" />
<xsd:element name="child3" type="xsd:string" />
</xsd:choice>
<xsd:attribute name="att2" type="xsd:string" use="required" />
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

</xsd:schema>
redefine.xsd
<?xml version="1.0"?>
<xsd:schema targetNamespace="http://inheritance-ext-res"
xmlns:tns="http://inheritance-ext-res"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">
            
<xsd:redefine schemaLocation="actual.xsd">
<xsd:complexType name="DerivedType">
<xsd:complexContent>
<xsd:extension base="tns:DerivedType">
<xsd:sequence>
<xsd:element name="child4" type="xsd:string" />
</xsd:sequence>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:redefine>

<xsd:element name="Redefine">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Base" type="tns:BaseType" />
<xsd:element name="Derived" type="tns:DerivedType" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>

</xsd:schema>
在以上模式中:

 

 

  1. 您在未更改其名称的情况下,通过向内容模型中添加一个或多个元素重新定义了名称为 DerivedType 的 complexType。
  2. 不在重定义模式中重新定义基类,它将按原样继承。

 

注意,重定义类型时,类型名称并不更改。所以,重定义的类型将其自身用作基类。

在以上示例中,我们重新定义了一个名为 DerivedType 的 complexType 而未更改其名称。重定义 DerivedType 时,对“DerivedType”的任何引用(例如,base="tns:DerivedType")都被认为是引用实际的 DerivedType。重定义类型后,对 DerivedType 的任何引用都被认为是引用重定义后的类型。

对应于以上重新定义的模式的 XML 实例如下:

<Redefine xmlns="http://inheritance-ext-res"
xmlns:xsi="http://www.w3.org/2001/XML Schema-instance"
xsi:schemaLocation="http://inheritance-ext-res redefine.xsd">

<Base att1="val">
<child1>This is base type</child1>
</Base>
  
<Derived att1="val" att2="val">
<child1>This is inherited from the base as is</child1>
<child2>This is added in the derived</child2>
<child4>This is added when redefining</child4>
</Derived>

</Redefine>
约束

 

身份约束

使用 XML 模式,您可以对元素和属性的内容实施唯一性约束,这可以保证指定元素或属性的值在实例文档中是唯一的。实施唯一性时,必须要有一个其值需要进行唯一性检查的项目,例如,ISBN 号。确定项目后,必须确定一个集合(例如,图书集),以在其中对这些选定的项目的值进行唯一性检查。

XML 模式为实施唯一性约束提供了两个结构: unique 和 key。Unique 确保当指定值不为空时,它们必须在定义的集合中是唯一的;key 确保指定值始终不为空,并在定义的集合中是唯一的。

还有一个结构 — keyref,它指向某个已定义的键。Keyref 确保 keyref 指向的键集中存在 keyref 中指定项目的值。

这三个结构的全都具有相同的语法(它们全都使用选择器和域),但含义不同。选择器用于定义集合,以在其中实施在其中实施唯一性,域(多个域用于定义一个组合项目)用于定义项目,以对其值进行唯一性检查。选择器和域的值均为 XPath 表达式。XPath 表达式不支持缺省命名空间,因此必须通过显式使用绑定到相应命名空间(如果命名空间中存在元素/属性)的前缀以使 XPath 表达式支持命名空间。例如:

<?xml version="1.0"?>
<xsd:schema targetNamespace="http://identity-constraint"
xmlns:tns="http://identity-constraint"
xmlns:xsd="http://www.w3.org/2001/XML Schema"
elementFormDefault="qualified">
attributeFormDefault="unqualified">


<xsd:complexType name="BookType">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="half-isbn" type="xsd:string" />
<xsd:element name="other-half-isbn" type="xsd:float" />
</xsd:sequence>
</xsd:complexType>

<xsd:element name="Books">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Book" type="tns:BookType" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>

<xsd:key name="isbn">
<xsd:selector xpath=".//tns:Book" />
<xsd:field xpath="tns:half-isbn" />
<xsd:field xpath="tns:other-half-isbn" />
</xsd:key>

</xsd:element>

</xsd:schema>
在以上模式中,我们声明了一个名为“isbn”的键,它表示由“field 指定的组合值不得为空,并在由 selector 指定的图书集中是唯一的”。

 

唯一粒子属性 (UPA) 约束

UPA 约束确保按以下方式指定每个元素的内容模型:在验证 XML 实例时,不存在模糊性,且可以明确确定正确的元素声明以进行验证。例如,以下模式违反了 UPA 约束:

<xsd:element name="upa">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="a" minOccurs="0"/>
<xsd:element name="b" minOccurs="0"/>
<xsd:element name="a" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
这是因为在以上模式的相应 XML 实例中:
<upa>
<a/>
</upa>
不能确定 XML 实例中的元素“a”对应于模式中的哪个元素声明 - 是位于“b”的元素声明之前“a”的元素声明,还是位于“b”的元素声明之后的“a”的元素声明。该限制使您只能编写上面的 XML 实例类型的 XMLSchema。在本示例中,如果您只将元素“b”的 minOccurs 设置为任何大于 0 的值,则不会违反 UPA。

 

因此,以下是一个有效模式:

<xsd:element name="upa">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="a" minOccurs="0"/>
<xsd:element name="b" minOccurs="1"/>
<xsd:element name="a" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
这是因为在以上模式的相应 XML 实例中:
<upa>
<a/>
<b/>
</upa>
显而易见的是,XML 实例中的元素“a”实际上是“a”的元素声明(它位于该模式中“b”的元素声明之前)实例。

 

结论

现在,您已经完成了本系列,您应了解以下内容:

 

  1. XML 和 XML 模式中的命名空间概念
  2. XML 模式中支持的标量数据类型以及如何使用 simpleType 进一步限制它们
  3. 元素内容、内容模型、模型组、粒子、扩展和限制 complexType、组装模式、标识约束和 UPA(用于定义和约束 XML 的结构)。

 

至此,您应已经较好地掌握了 XML 模式。

XML第三讲:XML处理模式 XML处理模式 一、 DOM 文档对象模式 1.DOM特点: 以树型结构访问XML文档。 一棵DOM树包含全部元素节点和文本节点。可以前后遍历树中的每一个节点。 整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能。 将整个文档调入内存(包括无用的节点),浪费时间和空间。 一旦解析了文档还需多次访问这些数据;硬件资源充 阅读详情

相关推荐

1、XML模式的使用和开发:构建可靠的XML文档结构

本文深入探讨了XML模式的使用和开发,重点介绍了W3C XML模式如何帮助构建可靠的XML文档结构。内容涵盖XML模式的基本作用(如验证、文档化、查询支持、数据绑定和导向编辑),W3C XML模式的优势与特性,以及其对复杂类型、简单类型、命名空间和模块化设计的支持。通过实例演示了XML模式在实际应用中的灵活性和强大功能,为开发者提供全面指导以提高XML文档的一致性、可维护性和扩展性。

garlic的博客 69

XML详细讲解(在java需掌握的程度)<一>:如何写XML文件——DTD约束&Schema约束

一天掌握xml!!!肝肝肝!!!

m0_62135731的博客 3315

全面掌握XML模式的权威指南

本文还有配套的精品资源,点击获取 简介:XML模式是XML的规范,用于规定XML文档的结构和数据类型,保证数据的准确性和一致性。本教程将详细介绍XML模式的各个方面,包括其基本构成、命名空间、数据类型定义、约束以及模式文档的组织结构。学习本教程,将有助于深入理解XML文档的结构控制,提高数据处理的效率和准确性,对于Web服务开发、配置文件管理等具有重要价值。 1....

weixin_35370061的博客 1107

XML和Schema命名空间详解

XML和Schema具有无关平台,技术厂商,简单,规范统一等特点,极具开放性,所以使用极为广泛,而且使用简单,在XML和Schema和,个人认为比较不好理解的一点是其命名空间问题,在这篇博客里详细进行理解。     名称空间是W3C推荐标准提供的一种统一命名XML文档中的元素和属性的机制。使用名称空间可以明确标识和组合XML文档中来自不同标记词汇表的元素和属性,避免了名称之间的冲突。

在你最感兴趣的事物上,隐藏着你人生的秘密 3万+

xsd-validator:根据XML模式验证XML文件

XSD验证器 根据XML模式(xsd文件)快速轻松地验证XML文件。 需要安装Java。 在Mac和Linux上的用法: ./xsdv.sh test.xsd test.xml Windows命令提示符下的用法: xsdv test.xsd test.xml 如果您发现它有用并且想要在系统范围内安装(仅适用于Linux / Mac): sudo ant install xsdv test.xsd test.xml 注意,该项目只是用于XML Schema验证的标准Java库例程的简单包装。

Android开发者必看:火山引擎API验签实战,5分钟搞定年龄变化接口调用

本文为Android开发者提供火山引擎API验签实战指南,重点解析HMAC-SHA256签名算法实现,并以年龄变化接口为例展示完整调用流程。通过OkHttp封装和性能优化建议,帮助开发者5分钟内快速集成火山引擎人像处理功能,解决API调用中的签名验证、参数编码等核心问题。

weixin_30342209的博客 317

XML与设计模式

XML与设计模式

lmz的博客 990

【阿里云大模型高级工程师ACP习题集】2.1 用大模型构建新人答疑机器人

【摘要】这是我精心整理出对应的习题集,里面足足有 30 道题目,从基础概念到深度拓展,全方位覆盖章节重点、难点。不管你是想检验自己的学习成果,还是想针对薄弱环节进行强化训练,它都能完美适配!

davidkorhenn的博客 2607

XML Schema命名空间:xmlns介绍

XML和Schema具有无关平台,技术厂商,简单,规范统一等特点,极具开放性,所以使用极为广泛,而且使用简单,在XML和Schema和,名称空间是W3C推荐标准提供的一种统一命名XML文档中的元素和属性的机制。使用名称空间可以明确标识和组合XML文档中来自不同标记词汇表的元素和属性,避免了名称之间的冲突。 .DTD、.XSD文件用于确定以及约束XML的语法。使用过DTD的人应该知道,命名冲突是

Aeroleo的博客 4317

避坑指南:Livox Mid-360双雷达SLAM配置中,那些官方文档没说的细节(IP设置、话题分离与时间同步)

本文详细解析了Livox Mid-360双雷达SLAM配置中的关键优化点,包括IP设置、话题分离与时间同步等官方文档未提及的细节。通过实战案例和代码示例,帮助开发者解决点云错位、IMU数据混乱等问题,提升SLAM系统的稳定性和精度。特别针对网络架构设计、驱动修改和时间同步机制提供了专业指导。

weixin_29745609的博客 425

linux 驱动 - pinctrl子系统

分析总结 pinctrl 子系统框架结构,平台 mtk6771 内核版本 kernel-4.4 , 本文所有的分析均基于此版本。

sty01z的博客 1557

java 解析XML的几种方式

第一种:DOM DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。 DO

smithdoudou88的专栏 526

微信小程序|基于小程序实现定位打卡功能

此文主要在小程序内实现打卡功能,可根据用户位置与公司设定的打卡范围实时判断打卡是否合法,并在后台对打卡记录进行管理。

商务合作 / 项目定制 / 学习交流。个人vx:lovely_wml 1万+

XML 模式:了解命名空间

XML 模式:了解命名空间 作者:Rahul Srivastava 迁移到 XML 模式?此命名空间介绍将帮助您了解其比较重要的组件之一。 根据Namespaces in XML W3C 推荐标准的定义,XML命名空间是由国际化资源标识符 (IRI) 标识的 XML 元素和属性集合;该集合通常称作 XML“词汇”。 定义 XML 命名空间的主要动机之一是在使用和重用多个词汇时避免名称冲突。XML 模式用于为 XML 实例创建一个词汇并频繁使用命名空间。因...

舞鹤白沙编码日志 401

YOLO11改进-注意力-引入自调制特征聚合模块SMFA

SMFA(自调制特征聚合模块): SMFA模块用于协同建模局部和非局部信息,它分为两个分支:一个是EASA(Efficient Approximation of Self-Attention,简化的自注意力分支),用于捕获非局部信息;另一个是LDE(Local Detail Estimation,局部细节估计分支),用于捕获局部细节。EASA通过对输入特征进行下采样,然后利用全局特征的方差进行调制,再与原始特征进行聚合,提取非局部结构信息。LDE分支则通过卷积操作提取输入特征中的高频局部信息。

qq_64693987的博客 2208

【Unity】【WebRTC】如何用Unity而不是浏览器接收远程画面

之前几篇我们讨论了如何设置信令服务器,如何发送画面给远端以及如何用浏览器查看同步画面,今天来讨论如何实现Unity内部接收画面。看本篇之前请先看过之前将web服务器设置和基本远程画面功能的几篇博文。在Unity编辑器中打开一个示例项目,点击BroadCast按钮。4. 再点击Receiver按钮,Start。Build一个示例项目,并运行这个项目。启动Web.app。

每日出拳老爷子的博客 1721

xml 调用xml_引用XML模式

随着W3C对XML Schema规范的最新定稿,您可能要开始使用模式。 与使用DTD(文档类型定义)相比,模式在定义约束时具有更大的灵活性和特异性。 本技巧说明了使用模式的一个重要部分:如何在文档中引用它们。 即使其他人正在编写模式,您可能也需要知道如何在XML文档中引用它们。 DTD的旧时代 首先,让我给您一个快速的比较参考。 在使用XML Schema之前,每个人都使用DTD进行约...

cuyi7076的博客 2010

13、网络通信中的字节序与内存测试

本文主要探讨了网络通信中的字节序问题以及嵌入式系统中内存测试的相关内容。在网络通信部分,重点分析了大端序和小端序的差异,以及TCP/IP协议中字节序的转换机制,并介绍了相关的宏定义和实现方法。在内存测试部分,详细阐述了内存测试的目的、常见问题以及具体的测试策略,包括数据总线测试、地址总线测试和设备测试。通过这些内容,嵌入式程序员可以更好地理解并解决实际开发中可能遇到的字节序和内存问题,从而提高系统的稳定性和可靠性。

mmm90的博客 111

xml的验证模式

xml的验证模式保证了XML文件的正确性, 常用的验证模式有两种: DTD 和XSD. DTD DTD ( Document Type Definition )即文挡类型定义,是一种 XML 约束模式语言,是 XML 文件的验证机制,属于 XML 文件组成的一部分。 DTD 是一种保证 XML 文档格式正确的有效 方法,可以通过比较 XML 文档和 DTD 文件来看文档是否符合规范...

m0_37564426的博客 585

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

(转)XML 模式:了解数据类型

作者:Rahul Srivastava 了解在 XML 模式 1.0 版中支持的数据类型以及如何使用它们 为本文提供的下载· Oracle XML 开发人员工具包W3C XML 模式数据类型规范为验证元素内容和属性值定义了许多数据类型。这些数据类型可以只用于验证元素的标量内容,而不验证非标量或混合内容。通常将 和 元素标记之间包含的文本以及属性的值称

feilovemichael的专栏 748

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

了解XML

1. XML 1.1 XML概述 Extensible Markup Language 可拓展标记语言 用途: 1. 数据存储,小型数据库,存在一定的CRUD操作可行性 2. 网络端数据的传输 3. JavaWEB框架项目配置文件 Spring Druid .... w3c万维网联盟指定的规范 1.2 基本语法 1. XML文件后缀名是.xml 2. XML第一行是对于当前文件的定...

qq_40197991的博客 1778

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

结构型模式:组合模式

组合模式(Composite Pattern)是一种强大的结构型设计模式,它允许将对象组合成树形结构以表示"部分-整体"的层次关系。这种模式的精髓在于客户端可以统一处理单个对象和对象组合,无需区分它们之间的差异。组合模式的核心思想是将单个对象(叶子节点)和组合对象(容器节点)一视同仁,从而使得客户端代码能够以相同的方式处理单个对象和对象的集合。这种设计实现了"多个对象组合成为一个对象"的无缝操作,极大地简化了处理复杂层次结构的代码。

Luck_ff的博客 838

设计模式、XML

设计模式 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。 其实还有两类:并发型模式和线程...

hao_dream_xi的博客 615

xml描述uml_使用UML设计XML模式

使用UML框架构造XML模式时,必须考虑三个问题: UML和XML模式之间的互补性 如何扩展UML以捕获模式提供的所有功能 从UML图设计XML模式的能力 为了在这种情况下帮助讨论这两个框架,我将使用一个虚拟公司的示例:BALTIC Shipping。 BALTIC Shipping是一家国际运输公司,专门从事从美国到东欧的运输。 它寻求建立一种机制来跟踪从纽约总部到其...

cuyi7076的博客 1781

Spring中XML的验证模式

XML文件的验证模式保证了XML文件的正确性,而比较常用的验证模式有两种:DTD、XSD. DTD与XSD的区别 一、DTD(Document Type Definition)即文档型定义,是一种XML约束模式语言,是XML文件的验证机制,是XML文件组成的一部分.他可以通过比较XML文档和DTD文件来看文档是否符合规范,元素和标签是否使用正确. 一个DTD文档包含:元素的定义规则,元素间关系的定义规则,元素可使用的属性,可使用的实体或符号规则. DTD的引入分为两种方式: 内部引用 内部引用应当通过下面的

qq_40708942的博客 848
上一篇: xml 总结(一)数据岛,命名空间
下一篇: XML总结(二)Schema
baobeiSimple
博客等级 码龄20年 61粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值