XML Schema补充材料(XSD)

XML Schema补充材料(XSD

1. XSD模式文档的编写规范

有人会问,DTDSchema都是对XML文档的一种约束,为什么不就选其中之一,而又有Schema呢。因为DTD安全度太低了,也就是说它的约束定义能力不足,无法对XML实例文档做出更细致的语义限制。其实细心的人会发现,在DTD中,只有一个数据类型,就是PCDATA(用在元素中)和CDATA(用在属性中),在里面写日期也行,数字还行,字符更是没问题。而Schema正是针对这些DTD的缺点而设计的,Schema是完全使用XML作为描述手段,具有很强的描述能力,扩展能力和处理维护能力等。下面让我们看一个简单的例子吧:

 

hello.xml

-------------------

<?xml version="1.0"?>

<greeting>Hello World!!</greeting>

 

说明:

一个根元素:greeting;且这个元素不含属性,无子元素,内容是字符串。

 

hello.xsd

----------

1. <?xml version="1.0"?>

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

3.      <xsd:element name="greeting" type="xsd:string"/>

4. </xsd:schema>

 

说明:

XML Schema文档后缀名是.xsd,完全符合XML语法,根元素是schema,命名空间xmlns:xsd="http://www.w3.org/2001/XMLSchema,用元素<element>定义实例文档中的元素,如greetingxsd:string就是定义的数据类型了,其中的数据类型有很多,比如:int,double,dateTime,Boolean,long,integer,float,等,总之Java等语言里有的数据类型它都有,但要以“xsd:”开头。

让我们再看一个里面有子无素的例子:

 

customer.xml

-----------

<customer>

    <name>teiki</name>

    <address>No.237, Road Waitan, Shanghai</address>

</customer>

 

则可以写出以下的XML Schema文档:

 

customer.xsd

----------------

1: <?xml version="1.0"?>

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

3: <xsd:element name="customer">

4:  <xsd:complexType>

5:  <xsd:sequence>

6:      <xsd:element name="name" type="xsd:string"/>

7:      <xsd:element name="address" type="xsd:string"/>

8:  </xsd:sequence>

9:  </xsd:complexType>

10: </xsd:element>

11: </xsd:schema>

 

说明:

实例文档customer.xml中,<customer>元素含有两个子元素,Schema中凡是有两个以上的子元素,就认为是复杂类型,所以我们在Schema文档中采用complexType来定义该元素。表示有多个XML子元素。sequence表示子元素依次出现的顺序,choice可以表示在多个子元素中选择一个,all表示多个子元素可以按任意次数出现。如果有多层子元素怎么办呢,同样的道理,有几层写几层,一直往下嵌就OK了,这里我要说的是另一种方法,结构看上去会清晰一些。

 

address.xml

---------------

<customer>

    <name>Teiki</name>

    <address>

    <!--address追加一个地址子元素-->

    <prefecture>Zhejiang</prefecture>

        <city>Hangzhou</city>

        <street>Xihu Road, No.121, 7F</street>

    </address>

</customer>

 

下面就是采用ref元素来编写的这个Schema文档:

 

address.xsd

-------------------

1:  <?xml version="1.0"?>

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

3:

4:  <xsd:element name="customer">

5:  <xsd:complexType>

6:  <xsd:sequence>

7:      <xsd:element name="name" type="xsd:string"/>

8:      <xsd:element ref="address"/>

9:  </xsd:sequence>

10: </xsd:complexType>

11: </xsd:element>

12:

13: <xsd:element name="address">

14: <xsd:complexType>

15: <xsd:sequence>

16:     <xsd:element name="prefecture" type="xsd:string"/>

17:     <xsd:element name="city" type="xsd:string"/>

18:     <xsd:element name="street" type="xsd:string"/>

19: </xsd:sequence>

20: </xsd:complexType>

21: </xsd:element>

22:

23: </xsd:schema>

 

说明:

如果按正常的写法,应该把1321行的内容替换到第8行去,但这里使用ref元素可以直接将其指向另一个模块,使文档更加具有可读性。如果元素中包含属性怎么办呢?一样简单,只要在定义完子元素的后面再接着定义属性就行了。定义属性用“attribute”,还是举个例子吧:

 

customer2.xml

---------------

<customer id="001718">

    <name>Teiki</name>

    <address>No.237, Road Waitan, Shanghai</address>

</customer>

 

这个例子和上面的一个例子差不多,只是在元素customer中设了一个属性id

 

customer2.xsd

------------------

1:  <?xml version="1.0"?>

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

3:

4:  <xsd:element name="customer">

5:  <xsd:complexType>

6:  <xsd:sequence>

7:      <xsd:element name="name" type="xsd:string"/>

8:      <xsd:element name="address" type="xsd:string"/>

9: </xsd:sequence>

10: <!--增加属性定义-->

11:     <xsd:attribute name="id" type="xsd:string"/>

12: </xsd:complexType>

13: </xsd:element>

14:

15: </xsd:schema>

 

说明:

需要注意的一点是,属性和元素不是一家的,所以要把它放在sequence外面写,但它们都在customer的孩子,所以要写在complexType的里面。

下面再看一个例子:

 

order.xsd

----------------------

1:  <?xml version="1.0"?>

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

3:

4:  <xsd:element name="order">

5:  <xsd:complexType>

6:  <xsd:sequence>

7:      <xsd:element ref="orderItem" maxOccurs="10"/>

8:  </xsd:sequence>

9:  </xsd:complexType>

10: </xsd:element>

11:

12: <xsd:element name="orderItem">

13: <xsd:complexType>

14: <xsd:sequence>

15: <xsd:choice>

16:     <xsd:element name="id" type="idType"/>

17:     <xsd:element name="name" type="xsd:string"/>

18: </xsd:choice>

19:     <xsd:element name="quantity" type="quantityType"/>

20: </xsd:sequence>

21: </xsd:complexType>

22: </xsd:element>

23:

24: <xsd:simpleType name="idType">

25: <xsd:restriction base="xsd:string">

26:     <xsd:enumeration value="7-5058-3496-7"/>

27:     <xsd:enumeration value="7-5005-6450-3"/>

28:     <xsd:enumeration value="7-3020-6069-7"/>

29: </xsd:restriction>

30: </xsd:simpleType>

31:

32: <xsd:simpleType name="quantityType">

33: <xsd:restriction base="xsd:integer">

34:     <xsd:minInclusive value="1"/>

35:     <xsd:maxInclusive value="10"/>

36: </xsd:restriction>

37: </xsd:simpleType>

38:

39:</xsd:schema>

 

上面的例子中,maxOccurs代表:相同元素最多出现的次数,与其相反的是minOccurs代表:出现的最少次数。默认情况下两个都为“1”,如果把minOccurs设为“0”,表示该元素可有可无choice代表:可选的元素,也就是在这里面写的元素只能选其中之一,不能全选。simpleType代表自定义数据类型,也就是name里的并不是真正的数据类型,而是根据自己的意愿定制的。restriction代表对某一数据类型做约束,也就是只能取其范围之内符合要求的数据,比如第2529行中,里面有个元素enumeration代表枚举,也就是只能在枚举的那几个中选一个,而下面的3336行,里面有一对元素minInclusivemaxInclusive代表类型的取值范围,也就是只能取大于等于minInclusive并且小于等于maxInclusive的数。把这个Schema用在XML中是这样的:

 

order.xml

----------------------

<?xml version="1.0" encoding="UTF-8"?>

<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="D:/ProgramCode/Year2/XML/practice/order.xsd">

    <orderItem>

        <id>7-5005-6450-3</id>

        <quantity>3</quantity>

    </orderItem>

    <orderItem>

        <name>xyb</name>

        <quantity>3</quantity>

    </orderItem>

    <!-- 注意下面这个是错的,因为超出了规定的范围 -->

    <orderItem>

        <id>7-5005-6450-3</id>

        <quantity>13</quantity>

    </orderItem>

    <!--从上面的注释到此,是错误的-->

</order>

 

说明:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"导入Schema的命令,D:/ProgramCode/Year2/XML/practice/order.xsdSchema文件的路径,如果用XMLSPY写时,会自动加上。对属性的设置,基本上和元素差不多。把上面的基本元素idquantity改成元素orderItem的属性,文档片断如下:

 

Order-1.xsd

----------------------

1.  <xsd:element name="orderItem">

2.  <xsd:complexType>

3.  <xsd:sequence></xsd:sequence>

4.      <xsd:attribute name="id" type="idType" use="required"/>

5.      <xsd:attribute name="quantity" type="xsd:integer" default="1"/>

6.  </xsd:complexType>

7.

8.  <xsd:simpleType name="idType">

9.  <xsd:restriction base="xsd:string">

10.     <xsd:pattern value="/d{1}-/d{4}-/d{4}-/d{1}"/>

11. </xsd:restriction>

12. </xsd:simpleType>

13. </xsd:element>

 

这里我们讲id属性类型作为一种自定义数据类型idType,它的格式就是上面用到的也就是类似于“7-5005-6450-3样的。而且,用attribute元素的use属性来定义是否是必须的属性required是必须值,optional是可选值,prohibited是无属性值。default属性是默认值。Pattern元素的属性value定义的值必须是一个正则表达式,由其限定的数据类型的值必须与其指定的模式匹配。/d{4}含义是只能由09之间的数字组成的长度为4个字符的字符串,如“0123”、“3229”等是合法的,而“a213”、“abdf”、“12345”等是不合法的。/d{1}-/d{4}-/d{4}-/d{1}的格式是x-xxxx-xxxx-x,其中x09之间的数字。对应的XML文档如下:

 

Order-1.xml

----------------------

<?xml version="1.0" encoding="UTF-8"?>

<order xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="order-1.xsd">

    <orderItem id="7-5005-6450-3" quantity="1"/>

    <orderItem id="7-3020-6069-7" quantity="2"/>

</order>

 

上面的属性定义还可以采用属性组attributeGroup来重新改写Schema文档。文档片断如下:

 

Order-2.xsd

----------------------

1:  <xsd:element name="orderItem">

2:    <xsd:complexType>

3:    <xsd:sequence></xsd:sequence>

4:       <xsd:attributeGroup ref="orderItemAttributes"/>

5:    </xsd:complexType>

6:  </xsd:element>

7:

8:  <xsd:attributeGroup name="orderItemAttributes">

9:     <xsd:attribute name="id" type="idType" use="required"/>

10:    <xsd:attribute name="quantity" type="xsd:integer" default="1"/>

11: </xsd:attributeGroup>

 

一个完整订书的Schema文档:

 

1:  <?xml version="1.0"?>

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

3:

4:    <xsd:element name="order">

5:      <xsd:complexType>

6:        <xsd:sequence>

7:          <xsd:element ref="orderItem" maxOccurs="10"/>

8:        </xsd:sequence>

9:      </xsd:complexType>

10:    </xsd:element>

11:

12:    <xsd:element name="orderItem">

13:      <xsd:complexType>

14:        <xsd:sequence></xsd:sequence>

15:        <xsd:attributeGroup ref="orderItemAttributes"/>

16:      </xsd:complexType>

17:    </xsd:element>

18:

19:    <xsd:attributeGroup name="orderItemAttributes">

20:      <xsd:attribute name="id" type="idType" use="required"/>

21:      <xsd:attribute name="quantity" type="xsd:integer" default="1"/>

22:    </xsd:attributeGroup>

23:

24:    <xsd:simpleType name="idType">

25:      <xsd:restriction base="xsd:string">

26:        <xsd:pattern value="/d{1}-/d{4}-/d{4}-/d{1}"/>

27:      </xsd:restriction>

28:    </xsd:simpleType>

29:

30: </xsd:schema>

 

XSD中定义元素的命名空间

一个XML schemaelementFormDefault=""这一属性用来指示XML Schema处理程序把这个XML schema中定义的元素或者类型放到哪个命名空间。

一个schema中声明的元素或者类型只能归到两种命名空间中的某一种中,这两种命名空间是:无名命名空间和由targetSchema属性指明的目标命名空间。而targetSchema属性只能在xsschema的定义中声明,因而,一个schema中定义的元素或类型只可能归属于一个有名命名空间,但是当不声明targetSchema属性时归属无名命名空间。

elementFormDefault="qualified"时,所有全局元素及其子元素将被以缺省方式放到目标命名空间;而当elementFormDefault="unqualified"时,全局元素放到目标命名空间,所有全局元素的子元素将被以缺省方式放到无名命名空间。而属性的命名空间类似地由attributeFormDefault=""来指明。

需要明白的是,elementFormDefault=""是有作用域的,并且是被继承的,除非在子定义中覆盖父定义。

下面三个例子说明了elementFormDefault的使用效果。红色表示属于已命名空间的元素,蓝色表示属于未命名空间的元素。

 

1.定义了目标命名空间,全局elementFormDefault=unqualified”。这时除了全局元素或者类型将归于目标命名空间外,局部元素将归于无名命名空间。

 

unqualified.xsd

――――――――――

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mywebsite.com/xml" elementFormDefault="unqualified" attributeFormDefault="unqualified">

 <xs:element name="c">

  <xs:complexType>

   <xs:sequence>

    <xs:element name="c1" type="xs:double"/>

    <xs:element name="c2" type="xs:string"/>

   </xs:sequence>

  </xs:complexType>

 </xs:element>

</xs:schema>

 

unqualified.xml

―――――――――

<?xml version="1.0" encoding="UTF-8"?>

<n:c xmlns:n="http://www.mywebsite.com/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mywebsite.com/xml

unqualified.xsd">

    <c1>3.14159265358979</c1>

    <c2>String</c2>

</n:c>

 

2.定义了目标命名空间,全局elementFormDefault=qualified”。这时全局元素或者类型将归于目标命名空间,局部元素将以缺省方式归于目标命名空间。

 

qualified.xsd

――――――――――

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mywebsite.com/xml" elementFormDefault="qualified" attributeFormDefault="unqualified">

 <xs:element name="c">

  <xs:complexType>

   <xs:sequence>

    <xs:element name="c1" type="xs:double"/>

    <xs:element name="c2" type="xs:string"/>

   </xs:sequence>

  </xs:complexType>

 </xs:element>

</xs:schema>

 

qualified.xml

―――――――――

<?xml version="1.0" encoding="UTF-8"?>

<c xmlns="http://www.mywebsite.com/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mywebsite.com/xml

qualified.xsd">

    <c1>3.14159265358979</c1>

    <c2>String</c2>

</c>

 

3.定义了目标命名空间,全局elementFormDefault=unqualified”。这时全局元素(c)或者类型将归于目标命名空间。局部元素(c1c2)以缺省方式归于无名命名空间。局部元素(c3)在局部定义中使用form=qualified”覆盖全局设定的unqualified,这使得c3归于目标命名空间(如果它有子元素,子元素将以缺省方式归于目标命名空间)。

 

qualified-1.xsd

―――――――――

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.mywebsite.com/xml" elementFormDefault="unqualified" attributeFormDefault="unqualified">

 <xs:element name="c">

  <xs:complexType>

   <xs:sequence>

    <xs:element name="c1" type="xs:double"/>

    <xs:element name="c2" type="xs:string"/>

    <xs:element name="c3"  type="xs:integer"  form="qualified"/>

   </xs:sequence>

  </xs:complexType>

 </xs:element>

</xs:schema>

 

qualified-1.xml

-------------------------

<?xml version="1.0" encoding="UTF-8"?>

<n:c xmlns:n="http://www.mywebsite.com/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mywebsite.com/xml

qualified-1.xsd">

    <c1>3.14159265358979</c1>

    <c2>String</c2>

    <n:c3>0</n:c3>

</n:c>

 

4. 总结:

targetNamespace是来限定schema中定义的元素和属性的名称空间,而elementFormDefault="qualified"是用来限定它将验证的XML文件是否使用targetNamespace指定的名称空间。

 

qualified-2.xsd

--------------------------

<?xml version="1.0" encoding="UTF-8"?>

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

        xmlns:po="http://www.example.com/PO1"

        targetNamespace="http://www.example.com/PO1"

        elementFormDefault="qualified"

        attributeFormDefault="qualified">

 

  <element name="purchaseOrder" type="po:PurchaseOrderType"/>

  <element name="comment"       type="string"/>

 

  <complexType name="PurchaseOrderType">

    <sequence>

      <element name="shipTo"    type="po:USAddress"/>

      <element name="billTo"    type="po:USAddress"/>

      <element ref="po:comment" minOccurs="0"/>

      <!-- etc. -->

    </sequence>

    <!-- etc. -->

  </complexType>

 

  <complexType name="USAddress">

    <sequence>

      <element name="name"   type="string"/>

      <element name="street" type="string"/>

      <!-- etc. -->

    </sequence>

  </complexType>

 

  <!-- etc. -->

</schema>

 

qualified-2.xml

--------------------------

<?xml version="1.0" encoding="UTF-8"?>

<po:purchaseOrder xmlns:po="http://www.example.com/PO1"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/PO1 qualified-2.xsd">

       <po:shipTo>

              <po:name>String</po:name>

              <po:street>String</po:street>

       </po:shipTo>

       <po:billTo>

              <po:name>String</po:name>

              <po:street>String</po:street>

       </po:billTo>

       <po:comment>String</po:comment>

</po:purchaseOrder>

 

 

注:

本资料来源于“中国XML论坛”,网址:http://bbs.xml.org.cn/index.asp

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值