XML 文档定义的两种形式(DTD,SCHEMA)

xml schema 与 xml dtd 区别:

XML Schema和DTD都用于文档验证,但二者还有一定区别,本质区别:schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的)。另外:

XML Schema是内容开放模型,可扩展,功能性强;而DTD可扩展性差;

XML Schema支持丰富的数据类型,而DTD不支持元素的数据类型,对属性的类型定义也很有限;

XML Schema支持命名空间机制,而DTD不支持;

XML Schema可针对不同情况对整个XML文档或文档局部进行验证;而DTD缺乏这种灵活性;

XML Schema完全遵循XML规范,符合XML语法,可以和DOM结合使用,功能强大;而DTD语法本身有自身的语法和要求,难以学习;

1.                  最简单的Schema文档
如何写一个最简单的XML Schema文档呢?

首先,我们写出一个最简单的XML文档。

hello.xml

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

<?xml version="1.0"?>

<greeting>Hello World!!</greeting>

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

hello.xsd

----------

<?xml version="1.0"?>

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

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

XML Schema文档后缀名是.xsd,完全符合XML语法,根元素是schema,命名空间xmlns:xsd="http://www.w3.org/2001/XMLSchema,用元素<element>定义实例文档中的元素,如greeting。

2.                  含子元素的Schema文档  
假设实例文档是如下的:

customer.xml

-----------

<customer>

<name>teiki</name>

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

</customer>

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

customer.xsd

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

<?xml version="1.0"?>

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

<xsd:element name="customer">

<xsd:complexType>

<xsd:sequence>

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

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

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

实例文档customer.xml中,<customer>元素含有两个子元素,所以我们在Schema文档中采用ComplexType来定义该元素。sequence表示子元素依次出现的顺序。

3.                  含子元素和孙元素的Schema文档 
这次我们给出一个更加复杂一些的文档:

customer.xml

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

<customer>

<name>Teiki</name>

<address>

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

<prefecture>Zhejiang</prefecture>

<city>Hangzhou</city>

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

</address>

</customer>

 

为此,我们需要一个更加复杂一点的Schema文档:

address.xsd

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

<?xml version="1.0"?>

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

<xsd:element name="customer">

<xsd:complexType>

<xsd:sequence>

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

<!-- 追加子元素address-->

<xsd:element name="address">

<xsd:complexType>

<xsd:sequence>

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

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

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

</xsd:sequence>

</xsd:complexType>

</xsd:element>

              </xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

不过,我们还可以采用ref元素来重新编写这个Schema文档:

address2.xsd

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

<?xml version="1.0"?>

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

<xsd:element name="customer">

<xsd:complexType>

<xsd:sequence>

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

<xsd:element ref="address"/>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name="address">

<xsd:complexType>

<xsd:sequence>

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

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

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

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

使用ref元素可以直接将其指向另一个模块,使文档更加具有可读性。

 

https://blog.csdn.net/sunxing007/article/details/5684265

每天都在用xml, 可是却一直没有去深入了解一下DTD和Schama, 当然我觉得很大一个原因是因为不需要, 本人从事web开发3年多也只有一次修改DTD文件的机会. 周末无意间翻看了一下张孝祥的书, 再到w3school上读了两边, 总算略知一二, 关键点记录下来, 以为纪念.

简单的说, DTD和Schema都是用来描述xml文档结构,限定文档的数据类型的. 只是做法上不一样. 想象一下一个xml 文档无非就是元素的集合, 元素可嵌套, 元素可以有属性. 那么DTD或schema就是用来描述一个xml文档可以出现哪些元素, 每个元素都可以有什么属性, 每个元素都可以有哪些嵌套元素, 元素可去什么数据类型, 以及元素的顺序, 重复的次数等等. 下面分别记录DTD和Schema的要点.

 

DTD:

1 DTD可以嵌入在XML文档中. 如下面的例子:

 

[xhtml] view plain copy

  1. <?xml version="1.0"?>  
  2. <!DOCTYPE note [  
  3.   <!ELEMENT note (to,from,heading,body)>  
  4.   <!ELEMENT to      (#PCDATA)>  
  5.   <!ELEMENT from    (#PCDATA)>  
  6.   <!ELEMENT heading (#PCDATA)>  
  7.   <!ELEMENT body    (#PCDATA)>  
  8. ]>  
  9. <note>  
  10.   <to>George</to>  
  11.   <from>John</from>  
  12.   <heading>Reminder</heading>  
  13.   <body>Don't forget the meeting!</body>  
  14. </note>  


2 DTD也可以独立的放在一个文件中. 如servlet2.3的部署描述文件xml, dtd文件引用了一个网络资源文件:

 

[xhtml] view plain copy

  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2.   <!DOCTYPE web-app PUBLIC  
  3.     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  
  4.     "http://java.sun.com/dtd/web-app_2_3.dtd" >  
  5. <web-app>  
  6. ...  
  7. </web-app>  

当然DTD文件也可以放在本地, 需要注意的是两者DOCTYPE的声明的不同:

 

[xhtml] view plain copy

  1. <?xml version="1.0"?>  
  2. <!DOCTYPE note SYSTEM "note.dtd">  
  3. <!-- 注意note.dtd要和本xml放在同目录下面 -->  
  4. <note>  
  5. <to>George</to>  
  6. <from>John</from>  
  7. <heading>Reminder</heading>  
  8. <body>Don't forget the meeting!</body>  
  9. </note>   

3 一个XML文档由以下模块构成:

元素 即一个节点 属性 提供有关元素的额外信息 实体 预定义的普通文本变量 PCDATA  会被解析器解析的文本, 这些文本将被解析器检查实体以及标记 CDATA 是不会被解析器解析的文本

则DTD分别用ELEMENT, ATTLIST, ENTITY, #PCDATA, #CDATA来描述.

4 关于ELEMENT:

<!ELEMENT 元素名称 EMPTY> 描述空元素(没有子节点和属性的元素), 如<!ELEMENT br EMPTY>.

<!ELEMENT 元素名称 (#PCDATA)> 描述只有PCDATA的元素, 如前面提到的<!ELEMENT from (#PCDATA)>.

<!ELEMENT 元素名称 ANY> 描述可包含任何可解析数据的组合. 不常用.

<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)> 描述元素包含的子元素序列.

如:<!ELEMENT note (to,from,heading,body)>.

当然可以限定元素出现的次数.如web-app_2_3.dtd:

<!ELEMENT web-app (icon?, display-name?, description?, distributable?,context-param*, filter*, filter-mapping*, istener*, servlet*,servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?,error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*,login-config?, security-role*, env-entry*, ejb-ref*,  ejb-local-ref*)>

也可以描述"或"关系:<!ELEMENT note (to,from,header,(message|body))> 即"note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,但 "message" 元素和 "body" 元素只能出现一个.

5 关于ATTLIST:

<!ATTLIST 元素名称 属性名称 属性类型 默认值> 声明元素拥有的属性.

<payment type="check" />对应的DTD描述: <!ATTLIST payment type CDATA "check">.

以下是属性类型的选项:

 

类型描述
CDATA值为字符数据 (character data)
(en1|en2|..)此值是枚举列表中的一个值
ID值为唯一的 id
IDREF值为另外一个元素的 id
IDREFS值为其他 id 的列表
NMTOKEN值为合法的 XML 名称
NMTOKENS值为合法的 XML 名称的列表
ENTITY值是一个实体
ENTITIES值是一个实体列表
NOTATION此值是符号的名称
xml:值是一个预定义的 XML 值

默认值参数可使用下列值:

 

解释
属性的默认值
#REQUIRED属性值是必需的
#IMPLIED属性不是必需的
#FIXED value属性值是固定的

如:<!ATTLIST contact fax CDATA #IMPLIED>, 则<contact fax="555-667788" />是合法的.

属性值可枚举:

<!ATTLIST 元素名称 属性名称 (en1|en2|..) 默认值>, 如:

<!ATTLIST payment type (check|cash) "cash">

6 关于实体

<!ENTITY 实体名称 "实体的值">, 如:

<!ENTITY writer "Bill Gates">
<!ENTITY copyright "Copyright W3School.com.cn">

则在xml中可以这样引用它们:

<author>&writer;&copyright;</author>

预定义的实体:

 

实体引用字符
&lt;<
&gt;>
&amp;&
&quot;"
&apos;'

下面是一个电视台的schedule和对应的DTD:

 

[xhtml] view plain copy

  1. <?xml version="1.0" standalone="no"?>  
  2. <!DOCTYPE tvschedule SYSTEM "TVSCHEDULE.dtd">  
  3. <tvschedule name="ANHUI WEISHI">  
  4.         <channel chan="123">  
  5.                 <banner>BANNEL 1</banner>  
  6.                 <day>  
  7.                         <date></date>  
  8.                         <holiday>HOLIDAY</holiday>  
  9.                 </day>  
  10.                 <day>  
  11.                         <date></date>  
  12.                         <programslot vtr="">  
  13.                                 <time></time>  
  14.                                 <title rating="" language="EN">12</title>  
  15.                                 <description></description>  
  16.                         </programslot>  
  17.                 </day>  
  18.         </channel>  
  19. </tvschedule>  

 

[xhtml] view plain copy

  1. <!ELEMENT tvschedule (channel+)>  
  2. <!ELEMENT channel (banner,day+)>  
  3. <!ELEMENT banner (#PCDATA)>  
  4. <!ELEMENT day (date,(holiday|programslot+)+)>  
  5. <!ELEMENT holiday (#PCDATA)>  
  6. <!ELEMENT date (#PCDATA)>  
  7. <!ELEMENT programslot (time,title,description?)>  
  8. <!ELEMENT time (#PCDATA)>  
  9. <!ELEMENT title (#PCDATA)>   
  10. <!ELEMENT description (#PCDATA)>  
  11.   
  12. <!ATTLIST tvschedule name CDATA #REQUIRED>  
  13. <!ATTLIST channel chan CDATA #REQUIRED>  
  14. <!ATTLIST programslot vtr CDATA #IMPLIED>  
  15. <!ATTLIST title rating CDATA #IMPLIED>  
  16. <!ATTLIST title language CDATA #IMPLIED>  

  

 

Schema:

Schema是DTD的替代者, 它比DTD可以做更多的事情:

定义可出现在文档中的元素 定义可出现在文档中的属性 定义哪个元素是子元素 定义子元素的次序 定义子元素的数目 定义元素是否为空,或者是否可包含文本 定义元素和属性的数据类型 定义元素和属性的默认值以及固定值

但是代价就是Schema比DTD更复杂.

XML Schema的引用:

 

[xhtml] view plain copy

  1. <?xml version="1.0"?>  
  2. <note  
  3. xmlns="http://www.w3school.com.cn"  
  4. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5. xsi:schemaLocation="http://www.w3school.com.cn/note.xsd">  
  6.   
  7. <to>George</to>  
  8. <from>John</from>  
  9. <heading>Reminder</heading>  
  10. <body>Don't forget the meeting!</body>  
  11. </note>  

note.xsd:

 

[xhtml] view plain copy

  1. <?xml version="1.0"?>  
  2. <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  
  3. targetNamespace="http://www.w3school.com.cn"  
  4. xmlns="http://www.w3school.com.cn"  
  5. elementFormDefault="qualified">  
  6.   
  7. <xs:element name="note">  
  8.     <xs:complexType>  
  9.       <xs:sequence>  
  10.     <xs:element name="to" type="xs:string"/>  
  11.     <xs:element name="from" type="xs:string"/>  
  12.     <xs:element name="heading" type="xs:string"/>  
  13.     <xs:element name="body" type="xs:string"/>  
  14.       </xs:sequence>  
  15.     </xs:complexType>  
  16. </xs:element>  
  17.   
  18. </xs:schema>  

 

由上面的代码可见, schema文件也是一个xml.

 

Schema命名空间:

schema有一个非常重要的概念就是命名空间(namespace).比如在spring中使用声明式事务管理的时候, 可以采用如下的配置方式为service层配置事务代理:

 

[xhtml] view plain copy

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"      
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  4.         xmlns:aop="http://www.springframework.org/schema/aop"    
  5.         xmlns:tx="http://www.springframework.org/schema/tx"    
  6.         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd     
  7.                 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd     
  8.                 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">    
  9.     <bean id="txManager">  
  10.         ......  
  11.     </bean>  
  12.     ......  
  13.     <tx:advice id="txAdvice" transaction-manager="txManager">    
  14.         <tx:attributes>    
  15.             <tx:method name="insert*" propagation="REQUIRED" />    
  16.             <tx:method name="update*" propagation="REQUIRED" />    
  17.             <tx:method name="delete*" propagation="REQUIRED" />    
  18.             <tx:method name="list" propagation="REQUIRED" read-only="true" />    
  19.         </tx:attributes>    
  20.     </tx:advice>    
  21.     <aop:config>    
  22.         <aop:pointcut id="interceptorPointCuts"    
  23.             expression="execution(* services.*Service(..))" />    
  24.         <aop:advisor advice-ref="txAdvice"    
  25.             pointcut-ref="interceptorPointCuts" />             
  26.     </aop:config>  
  27. </beans>  

那么这里使用了tx,aop命名空间.一个xml文档可以使用多个命名空间, 命名空间需要先声明, 并给它取别名, 然后依次给出每个命名空间的schema文件地址.如下代码解释希望可以帮助你理解上面臭长的命名空间声明:

 

[xhtml] view plain copy

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <root xmlns="默认命名空间,它不需要取别名"      
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  4.         xmlns:ns1别名="namespace1"    
  5.         xmlns:ns2别名="namespace2"    
  6.         xsi:schemaLocation="默认命名空间,它不需要取别名" "默认命名空间的xsd文件地址"     
  7.                 namespace1 namespace1的xsd文件地址  
  8.                 namespace2 namespace2的xsd文件地址>    
  9.         ......  
  10. </root>  

需要注意的是xsi命名空间几乎是必要的, 因为需要用xsi:schemaLocation来申明每个命名空间的schema文件地址.

对于上面给出的note.xsd. 因为它本身也是一个xml, 它要使用schema命名空间, 所以它也要申明命名空间.

鉴于schema的复杂性以及现实中没有多少机会编写一个xsd文件, 所以具体的关于schema的编写就不介绍了. 如有问题, 请参看:http://www.w3school.com.cn/schema/index.asp

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值