4【xml schema】复合指示器

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)指嵌套在其他元素中的元素。

posted @ 2017-09-05 15:42  MartinDing  阅读(296)  评论(0编辑  收藏  举报