8.1什么是复合元素(Complex Elements)?
复合元素(Complex Elements)是含有其他元素和/或属性的XML元素。
有四种复合元素(Complex Elements):
◆空元素
◆只含有其他元素的元素
◆只含有文本的元素
◆含有文本和其他元素的元素
注意:这些元素中的每一个也许还含有属性!
8.2复合元素(Complex Elements)的例子
一个空的复合XML元素"product":
<product pid="1345"/>
只含有其他元素的复合XML元素, "employee":
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
只含有文本的复合XML元素, "food":
<food type="dessert">Ice cream</food>
含有元素和文本的复合XML元素, "description":
<description>
It happened on <date lang="norwegian">03.03.99</date> ....
</description>
8.3怎样定义一个复合元素(Complex Elements)?
看这个只含有其他元素的复合XML元素,"employee":
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
我们有两种方法可以在一篇XML Schema里定义一个复合元素(Complex Elements):
①"employee"元素可以直接通过命名元素的方式被声明,像这样:
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
如果你用了上面的方法,那么只有"employee"元素才可以用指定的复合类型。注意子元素"firstname" 和 "lastname",它们是被包围在<sequence>“指示器”元素里的。这意味着子元素必须以它们被声明的顺序出现。
② "employee"元素可以有个类型属性,其所指的是要用的复合类型的名称:
<xs:element name="employee" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:element name="employee" type="personinfo"/>
<xs:element name="student" type="personinfo"/>
<xs:element name="member" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
你也可以在现存的复合元素(Complex Elements)上再加上一个复合元素(Complex Elements),并添加一些元素,就像这样:
<xs:element name="employee" type="fullpersoninfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="fullpersoninfo">
<xs:complexContent>
<xs:extension base="personinfo">
<xs:sequence>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
9.XSD Complex 空元素
一个空的复合元素不能含有内容,只能含有属性。
9.1复合空元素(Complex Empty Elements)
一个空的XML元素:
<product prodid="1345" />
上述"product"元素完全不含内容。为定义不含内容的类型,我们必须定义一个内容中只允许出现元素的类型,但我们不需要声明任何元素,就像这样:
<xs:element name="product">
<xs:complexType>
<xs:complexContent>
<xs:restriction base="xs:integer">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:element>
上述例子中,我们定义了一个有复合内容的复合类型。复合内容的元素表示了我们想要约束或扩充的复合类型的内容模式。对整数的约束声明了一个属性,但并没有介绍任何元素内容。
但是,可以更加简洁地声明"product"元素,就像这样:
<xs:element name="product">
<xs:complexType>
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
</xs:element>
或者你可以给complexType元素起个名称,并让"product"元素有个类型属性,而且类型属性引用的是complexType的名称(如果你用这个方法,几个元素可以引用相同的复合类型):
<xs:element name="product" type="prodtype"/>
<xs:complexType name="prodtype">
<xs:attribute name="prodid" type="xs:positiveInteger"/>
</xs:complexType>
10.XSD 复合类型 - 纯元素
“只有元素(Elements-only)”复合类型含有一个只包含其他元素的元素。
10.1复合类型只含有元素
一个XML元素, "person",只含有其他元素:
<person>
<firstname>John</firstname>
<lastname>Smith</lastname>
</person>
你可以在一篇schema里定义"person"元素,就像这样:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
注意<xs:sequence>标签。这表示所定义的元素("firstname" 和 "lastname")必须在"person"元素里以那样的次序出现。
或者你可以给complexType元素取个名字,让"person"元素有个类型属性,这个类型属性的名字可以参考使用complexType元素的名字(如果你用这个方法,几个元素可以同时参考使用相同的复合类型)。
<xs:element name="person" type="persontype"/>
<xs:complexType name="persontype">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
11.XSD 复合文字 - 纯元素
一个复合只含文本元素(Complex Text-Only Elements)可以含有文本和属性。
11.1复合只含文本元素(Complex Text-Only Elements)
这种类型只含有简单内容(文本和属性),因此我们在内容周围添加一个simpleContent元素,当用到简单内容时,你必须在simpleContent元素里定义一个扩展或约束,就像这样:
<xs:element name="somename">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="basetype">
....
....
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
OR
<xs:element name="somename">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="basetype">
....
....
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
</xs:element>
提示:用extension/restriction元素扩展或限制元素的基本简单类型(base simple type)。
这儿是只含有文本的一个XML元素, "shoesize":
<shoesize country="
下面的例子声明了一个复合类型,"shoesize"元素。内容定义为整数值,"shoesize"元件含有名为"country"的属性。
<xs:element name="shoesize">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
我们可以给complexType元件起个名字,让"shoesize"元件有种类属性,种类属性的名字就是complexType元件的名字。(如果你用这种方法,几个元素指的可以是相同的复合类型)
<xs:element name="shoesize" type="shoetype"/>
<xs:complexType name="shoetype">
<xs:simpleContent>
<xs:extension base="xs:integer">
<xs:attribute name="country" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
12.XSD 混合内容的复合类型
混合内容的复合类型元素(XSD Complex Types Element With Mixed Content )可以含有属性,元素,和文本。
12.1混合内容的复合类型
一个XML元素,"letter",既含有文本又含有其他元素:
<letter>
Dear Mr.<name>John Smith</name>.
Your order <orderid>1032</orderid>
will be shipped on <shipdate>
</letter>
下面的XML公式声明了"letter"元素:
<xs:element name="letter">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
</xs:element>
注意:为了使字符数据能出现在"letter"子元件之间,mixed属性必须设置为"true"。<xs:sequence>标签指出了已定义的元素(name, orderid 和shipdate)在"letter"元素里必须以指定的顺序出现。
我们可以给这个complexType元素一个名称,并且让"letter"元素有一个引用了complexType的名称的种类属性(如果你用了这个方法,几个元素可以同时使用相同的复合类型):
<xs:element name="letter" type="lettertype"/>
<xs:complexType name="lettertype" mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
13.XSD 指示器复合类型
用指示器(Indicators)我们可以控制文件中元素的使用方法(HOW TO USE)。
13.1指示器(Indicators)
有7种指示器(Indicators)
①顺序指示器(Indicators)
◆All 全部
◆Choice 选择
◆Sequence 按顺序
②出现次数指示器(Indicators)
◆maxOccurs 最多出现次数
◆minOccurs 最少出现次数
③组指示器(Indicators)
◆Group name 组名
◆attributeGroup name 属性组名称
13.2顺序指示器(Indicators)
顺序指示器(Indicators)用于指定元素的顺序。
①全部指示器(Indicators)
<all>指示器(Indicators)指明了子元件可以以任何次序出现,并且每个子元件只能出现一次:
<xs:element name="person">
<xs:complexType>
<xs:all>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:element>
注意:用<all>指示器(Indicators)时你可以把<minOccurs>指示器 (Indicators)设为0或1,<maxOccurs>指示器(Indicators)只能设为1。
②选择指示器(Indicators)
<choice>指示器(Indicators)指明了随便哪一个子元素都可以出现:
<xs:element name="person">
<xs:complexType>
<xs:choice>
<xs:element name="employee" type="employee"/>
<xs:element name="member" type="member"/>
</xs:choice>
</xs:complexType>
</xs:element>
③有序指示器(Indicators)
<sequence>指示器(Indicators)指定了子元素必须以一个指明的顺序出现:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
13.3出现次数指示器(Indicators)
出现次数指示器(Indicators)用于定义一个元素可以出现的次数。
注意:对所有的"Order"和"Group"指示器(Indicators)(any, all, choice, sequence,group name, 和 group reference)来说,maxOccurs 和 minOccurs的默认值都是1。
①最多出现次数指示器(Indicators)
最多出现次数指示器(Indicators)指明了一个元素可以出现的最多次数:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子指明了"child_name"元素在"person"元素里最少出现1次(minOccurs的默认值为1),最多出现10次。
②最少出现次数指示器(Indicators)
最少出现次数指示器(Indicators)指明了一个元素要出现的最小次数:
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
maxOccurs="10" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
上面的例子指明了"child_name"元素在"person"元素里最少出现0次(minOccurs的默认值为1),最多出现10次。
提示:为使元件可以重复出现无数次,可以设置maxOccurs="unbounded"的状态.
实际作用例子:
名为"Myfamily.xml"的XML文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns:xsi="http://www.w3.org.sixxs.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="family.xsd">
<person>
<full_name>Hege Refsnes</full_name>
<child_name>Cecilie</child_name>
</person>
<person>
<full_name>Tove Refsnes</full_name>
<child_name>Hege</child_name>
<child_name>Stale</child_name>
<child_name>Jim</child_name>
<child_name>Borge</child_name>
</person>
<person>
<full_name>Stale Refsnes</full_name>
</person>
</persons>
上面XML文件含有一个名为"persons"的根元素,这个根元素里面里我们已经定义了3个"person"元素。每个"person"元素必须含有一个"full_name"元素,而且最多可有5个"child_name"元素。
下面是名为"family.xsd"的schema文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org.sixxs.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="persons">
<xs:complexType>
<xs:sequence>
<xs:element name="person" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="full_name" type="xs:string"/>
<xs:element name="child_name" type="xs:string"
minOccurs="0" maxOccurs="5"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
13.4组指示器(Indicators)
组指示器(Indicators)用于定义相关的元素组。
①元素组
元素组要定义组声明,像这样:
<xs:group name="groupname">
...
</xs:group>
你必须在组声明里定义一个all, choice,或sequence元素。下面的例子定义了一个名为"persongroup"的组,这个定义了一组元素必须以一定顺序出现:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
定义了一个组后,你可以在另一个组参考它,像这样:
<xs:group name="persongroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="birthday" type="xs:date"/>
</xs:sequence>
</xs:group>
<xs:element name="person" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:group ref="persongroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
②属性组
属性组定义有attributeGroup(属性组)声明,像这样:
<xs:attributeGroup name="groupname">
...
</xs:attributeGroup>
下面的例子定义了叫做"personattrgroup"的一个属性组:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
定义了一个属性组之后,你可以在别的定义里参考它,像这样:
<xs:attributeGroup name="personattrgroup">
<xs:attribute name="firstname" type="xs:string"/>
<xs:attribute name="lastname" type="xs:string"/>
<xs:attribute name="birthday" type="xs:date"/>
</xs:attributeGroup>
<xs:element name="person">
<xs:complexType>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>
14.XSD <any> 元素
<any>元素可以使我们在XML文档中添加没有被schema 定义过的新元素从而扩充XML文档。
14.1<any>元素
<any>元素可以使我们在XML文档中添加没有被schema 定义过的新元素从而扩充XML文档。
下面的例子是名为"family.xsd"的一份XML schema片段。它展示了"person"元素的声明。用上<any>元素,我们可以在"person"元素的内容里扩充任意元素(在<lastname>的后面):
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:any minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
现在我们想在"person"元素中添加"children"元素,即使这篇schema的作者从未声明过什么"children"元素,我们也可以做到。
请看下面名为"children.xsd"的schema文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org.sixxs.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com.sixxs.org"
xmlns="http://www.w3schools.com.sixxs.org"
elementFormDefault="qualified">
<xs:element name="children">
<xs:complexType>
<xs:sequence>
<xs:element name="childname" type="xs:string"
maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
下面的XML文件(叫做"Myfamily.xml"),用上了来自"family.xsd" 和"children.xsd"两篇不同schema的组件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns="http://www.microsoft.com.sixxs.org"
xmlns:xsi="http://www.w3.org.sixxs.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.microsoft.com.sixxs.org family.xsd
http://www.w3schools.com.sixxs.org children.xsd">
<person>
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
<children>
<childname>Cecilie</childname>
</children>
</person>
<person>
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
</persons>
上述XML文件是有效的,因为"family.xsd" schema允许我们在"person"元素里的"lastname"元素后面扩充一个任意元素。
<any> 和<anyAttribute>元素是用于制造可扩展文档的!它们允许文档含有没有在主要XML schema里声明过的其它新元素。
15.XSD <anyAttribute> 元素
<anyAttribute>元素可使我们在XML文档中添加未被schema指定过的属性。
15.1<anyAttribute>元素
<anyAttribute>元素可使我们在XML文档中添加未被schema指定过的属性。
下面是名为"family.xsd"的XML schema片段。它显示了"person"元素的声明。通过使用<anyAttribute>元素我们可以给"person"元素添加任意数量的属性。
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
<xs:anyAttribute/>
</xs:complexType>
</xs:element>
现在我们想在"person"元素中添加"gender"属性,即使这篇schema的作者从未声明过什么"gender"属性,我们也可以做到。
请看下面名为"attribute.xsd"的schema文件:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org.sixxs.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com.sixxs.org"
xmlns="http://www.w3schools.com.sixxs.org"
elementFormDefault="qualified">
<xs:attribute name="gender">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="male|female"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:schema>
下面的XML文件(叫做"Myfamily.xml"),用上了来自"family.xsd" 和"attribute.xsd"两篇不同的schema组件。
<?xml version="1.0" encoding="ISO-8859-1"?>
<persons xmlns="http://www.microsoft.com.sixxs.org"
xmlns:xsi="http://www.w3.org.sixxs.org/2001/XMLSchema-instance"
xsi:SchemaLocation="http://www.microsoft.com.sixxs.org family.xsd
http://www.w3schools.com.sixxs.org attribute.xsd">
<person gender="female">
<firstname>Hege</firstname>
<lastname>Refsnes</lastname>
</person>
<person gender="male">
<firstname>Stale</firstname>
<lastname>Refsnes</lastname>
</person>
</persons>
上述XML文件是有效的,因为"family.xsd" schema允许我们在"person"元素里添加属性。
<any> 和<anyAttribute>元素是用于扩展文档的!它们允许文档含有没有在主要XML schema里声明过的其它新元素。
16.XSD 元素替代
用XML Schema,一个元素可替代另一元素。
16.1元素替代(Element Substitution)
假设有两个分别来自英国和挪威的使用者,我们很希望有能力能让他或她进行选择,在XML文档里的元素名称中选择他们所擅长的语言,是英文呢?还是挪威文呢?
为解决这个问题,我们在XML schema里定义了替代组(substitutionGroup)。首先,我们声明了一个标题元素,接着,我们声明已说明可替代标题元素的其他元素:
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
在上面的例子里,"name"元素是标题元素,"navn"元素可以替代"name"。
看下面的XML schema片段:
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo"/>
<xs:element name="kunde" substitutionGroup="customer"/>
一份有效 的XML文档(根据上述schema的XML文档)应该像这样:
<customer>
<name>John Smith</name>
</customer>
或者像这样:
<kunde>
<navn>John Smith</navn>
</kunde>
16.2关闭元素替代(Element Substitution)
为了防止其他元素被已指定的元素替代(Element Substitution),可以用block属性:
<xs:element name="name" type="xs:string" block="substitution"/>
看这段XML schema片段:
<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custinfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="custinfo" block="substitution"/>
<xs:element name="kunde" substitutionGroup="customer"/>
一份有效的XML文档(根据上述的schema的XML文档)应该像这样:
<customer>
<name>John Smith</name>
</customer>
但是这样就不再有效了:
<kunde>
<navn>John Smith</navn>
</kunde>
16.3使用替代组(substitutionGroup)
可替代元素类型应和标题元素的类型相同,或是从中派生出来的。如果可替代元素类型和标题元素的类型相同,你就不需要再指明可替代元素的类型了。
注意在可替代元素组里的所有元素(标题元素和可替代元素)必须声明为“全域元素(global element)”,否则它是不会作用的!