5 XSD 复合类型指示器
七种指示器
Order 指示器
- All
- Choice
- Sequence
Occurrence
- maxOccurs
- minOccurs
Group
- Group name
- attributeGroup name
Order 指示器 指示器用于定义元素的顺序。
All 指示器 指示器规定子元素可以按照任意顺序出现,且每个子元素必须只出现一次
<xs:element name="letter">
<xs:complexText mixed="true">
<xs:all>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexText>
</xs:element>
设置all 你可以把 <minOccurs> 设置为 0 或者 1,而只能把 <maxOccurs> 指示器设置为 1
<choice> 指示器规定可出现某个子元素或者可出现另外一个子元素(非此即彼)
如需设置子元素出现任意次数,可将 <maxOccurs> (稍后会讲解)设置为 unbounded(无限次)
<sequence> 规定子元素必须按照特定的顺序出现
Occurrence 指示器用于定义某个元素出现的频率。 对于所有的 "Order" 和 "Group" 指示器(any、all、choice、sequence、group name 以及 group reference),其中的 maxOccurs 以及 minOccurs 的默认值均为 1
maxOccur 规定某个元素可出现的最大次数
<xs:element name="child_name" type="xs:string" maxOccurs="10"/>
Group 指示器 指示器用于定义相关的数批元素 元数组
<xs:group name="组名称">
...
</xs:group>
group 必须定义 all、choice 或者 sequence 元素
<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="personalGroup">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="age" type="xs:integer"/>
</xs:sequence>
</xs:group>
<xs:element name="person" type="personal_info"/>
<xs:complexType name="personal_info">
<xs:sequence>
<xs:group ref="personalGroup"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
属性组
xs:attributeGroup
和上面一样的用法
<xs:attributeGroup name="personalAttGroup">
<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>
<xs:complexType>
<xs:attributeGroup ref="personalAttGroup"/>
</xs:complexType>
</xs:element>
DEMO
xsd 文件
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<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:sequence>
<xs:element name="hello" type="xs:string"/>
</xs:sequence>
<xs:attributeGroup ref="personattrgroup"/>
</xs:complexType>
</xs:element>
</xs:schema>
xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="test1.xsd" firstname="firstname"
lastname="lastname" birthday="2016-10-11">
<hello>content</hello>
</person>
上面代码中有个坑 为啥我要在原来的基础上 加了一个 xs:sequence 就是因为在xml中 我person 标签之间留了空格 sublime text 格式化代码(换了行) 然后验证的时候就报错 | 如果xsd没有sequence 那么person 必须是 <person ... /> 或者 <person></person>
使用ref 来引用
<any> 元素使我们有能力通过未被 schema 规定的元素来拓展 XML 文档!
文档的demo 我自己进行了模拟
DEMO1 #book.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns="http://cos-git.dev"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://cos-git.dev"
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>
对应的 demo.xml 如下
<?xml version="1.0" encoding="UTF-8"?>
<persons xmlns="http://cos-git.dev"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cos-git.dev book.xsd">
<person>
<full_name>Tony Smith</full_name>
<child_name>Cecilie</child_name>
</person>
<person>
<full_name>David Smith</full_name>
<child_name>Jogn</child_name>
<child_name>mike</child_name>
<child_name>kyle</child_name>
<child_name>mary</child_name>
<child_name>xh</child_name>
</person>
<person>
<full_name>Michael Smith</full_name>
</person>
</persons>
php 验证函数
<?php
$dom = new DOMDocument;
$dom->load('demo.xml');
if($dom->schemaValidate("book.xsd")){
echo "validate";
}else{
echo "not validate";
}
上面是单个xsd 文件的验证 验证通过
child 部分
child.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns="http://www.w3school.com.cn"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
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>
children.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<children
xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn child.xsd">
<childname>张</childname>
<childname>张s</childname>
</children>
php 验证函数
<?php
$dom = new DOMDocument;
$dom->load("children.xml");
if($dom->schemaValidate("child.xsd")){
echo "validate child";
}
我这里犯了几个错误
1.一个是xmlns 拼写错误 就会有这样的错误 PHP Warning: DOMDocument::schemaValidate(): /Users/dingmac/Desktop/xml_test/child.xsd:6: namespace error : Namespace prefix xlmns for xs on schema is not defined in /Users/dingmac/Desktop/xml_test/validate_children.php on line 5 没有定义的问题
2.xsd 中xmlns:xs="http://www.w3.org/2001/XMLSchema" 是这样的设置 而在 xml中使用的是 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 两个有点像 但是不一样 【不写不知道啊 一写都是错啊】
没有找到 验证多个 xsd的函数 知道的可以通知我不胜感激
xml 的写法应该是
<persons xmlns="http://cos-git.dev"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://cos-git.dev book.xsd http://www.w3school.com.cn child.xsd">
<person>
<full_name>Tony Smith</full_name>
<child_name>Cecilie</child_name>
<children>
<childname>Name</childname>
</children>
</person>
...
</persons>
<anyAttribute> 元素使我们有能力通过未被 schema 规定的属性来扩展 XML 文档!
在xsd 文件中 <xs:anyAttribute/>
另外一个xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.w3school.com.cn"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
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>
元素替换 使用Element Substitution
DEMO
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
首先,我们声明主元素,然后我们会声明次元素这些次元素可声明它们能够替换主元素 上面的代码中 name 是主元素 navn 是次元素
代码如下:
#substitution.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.w3school.com.cn"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3school.com.cn"
elementFormDefault="qualified">
<xs:element name="name" type="xs:string"/>
<xs:element name="navn" substitutionGroup="name"/>
<xs:complexType name="custominfo">
<xs:sequence>
<xs:element ref="name"/>
</xs:sequence>
</xs:complexType>
<xs:element name="custom" type="custominfo"/>
<xs:element name="kunde" substitutionGroup="custom"/>
</xs:schema>
#customer.xml
<?xml version="1.0" encoding="UTF-8"?>
<kunde
xmlns="http://www.w3school.com.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3school.com.cn substitution.xsd">
<name>校长</name>
</kunde>
其中 下面都是有效的
<customer>
<name></name>
</customer>
<kunde>
<name></name>
</kunde>
<kunde>
<navn></navn>
</kunde>
不允许 替换使用 block="substitution" 那样的话 就不可已使用这个标签
<xs:element name="name" type="xs:string" block="substitution"/>
<xs:element name="navn" substitutionGroup="name"/>
如果出现<kunde><navn></navn></kunde> 就会出错
可替换元素的类型必须和主元素相同,或者从主元素衍生而来。假如可替换元素的类型与主元素的类型相同,那么您就不必规定可替换元素的类型了。 请注意,substitutionGroup 中的所有元素(主元素和可替换元素)必须被声明为全局元素,否则就无法工作!
全局元素指 "schema" 元素的直接子元素!本地元素(Local elements)指嵌套在其他元素中的元素。