DTD文档的阅读和编写——web.xml报错不要再百度了

来源:互联网 发布:apache ignite 编辑:程序博客网 时间:2024/06/05 20:56

简介

文档类型定义(Document TypeDefinition ,dtd)是一套为了进行程序间的数据交换而建立的关于标记符的语法规则。它是标准通用标记语言和可扩展标记语言1.0版规格的一部分,文档可根据某种DTD语法规则验证格式是否符合此规则。文档类型定义也可用做保证标准通用标记语言、可扩展标记语言文档格式的合法性,可通过比较文档和文档类型定义文件来检查文档是否符合规范,元素和标签使用是否正确。文件实例提供应用程序一个数据交换的格式。使用各类文档类型定义是为了让标准通用标记语言、可扩展标记语言文件能符合规定的数据交换标准,因为这样,不同的公司只需定义好标准文档类型定义,就都能依文档类型定义建立文档实例,并且进行验证,如此就可以轻易交换数据,防止了个实例数据定义不同等原因造成的数据交换障碍,满足了网络共享和数据交互。文档类型定义文件是一个美国信息交换标准代码文本文件。

分类

DTD可以是一个完全独立的文件,像是Web应用中web.xml文档中开始的部分,另一种是在文档内部的DTD,它应该包装在一个DOCTYPE声明中:

<!DOCTYPE 根元素 [元素声明]>

如下含有内部DTD的XML文档:

<?xmlversion="1.0"?>

<!DOCTYPE person[

<!ELEMENT person(name,age)>

<!ELEMENT name(#PCDATA)>

<!ELEMENT age(#PCDATA)>

]>

<person>

<name>Gos</name>

<age>21</age>

</person>

以上DTD定义了当前XML中的元素(行号使用#Number表示):

#1     文档的是person类型的文档,也就是文档的根元素是<person>

#2     person元素有两个子元素name、age

#3     name属性为“#PCDATA”类型

#4     age属性为“#PCDATA”类型

外部声明

在*.dtd文档中的内容是上面<!DOCTYPE person[……]>中的内容,在使用该DTD文档的开始部分需要将*.dtd文档引入到当前XML文档中:

<!DOCTYPE 根元素 SYSTEM "文件名">

比如:

<!DOCTYPE person SYSTEM"person.dtd">

DTD语法规则

在XML文档中包含元素、属性、实体、PCDATA(parsed character data)、CDATA(character data),DTD需要对上面的内容的格式进行定义。

1.      元素

元素是XML以及HTML文档的主要构建模块。元素可包含文本、属性、子元素或者是空的。空的比如<hr/>、<br/>等。在一个 DTD 中,元素通过元素声明来进行声明,声明语法:

在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法:

<!ELEMENT元素名称类别>

或者

<!ELEMENT 元素名称 (元素内容)>

空元素

空元素通过类别关键词EMPTY进行声明:

<!ELEMENT元素名称EMPTY>

只有 PCDATA 的元素

只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:

<!ELEMENT元素名称 (#PCDATA)>

带有任何内容的元素

通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:

<!ELEMENT元素名称ANY>

带有子元素(序列)的元素

带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:

<!ELEMENT元素名称 (子元素名称 1)>

或者

<!ELEMENT元素名称 (子元素名称 1,子元素名称 2,.....)>

在DTD中元素出现的次数是使用几个运算符来规定的:

符号

元素出现的次数

1或0次

*

任意次

+

>=1

无符号

1次

2.      属性

属性可提供有关元素的额外信息。属性总是被置于某元素的开始标签中。属性总是以名称/值的形式成对出现的。比如:<person name=”XIAOMING” age=”21”/>

在 DTD 中,属性通过 ATTLIST 声明来进行声明。

声明属性

属性声明拥使用下列语法:

<!ATTLIST元素名称属性名称属性类型默认值>

以下是属性类型的选项:

类型描述

CDATA 值为字符数据 (characterdata)

(en1|en2|..) 此值是枚举列表中的一个值

ID 值为唯一的 id

IDREF 值为另外一个元素的 id

IDREFS 值为其他 id 的列表

NMTOKEN值为合法的 XML 名称

NMTOKENS 值为合法的 XML 名称的列表

ENTITY 值是一个实体

ENTITIES 值是一个实体列表

NOTATION 此值是符号的名称

xml: 值是一个预定义的 XML 值

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

值解释

属性的默认值

 

#REQUIRED

属性值是必需的

#IMPLIED

属性是可选的

#FIXED

属性值是固定的

规定一个默认的属性值

DTD:

<!ELEMENT square EMPTY>

<!ATTLIST square width CDATA"0">

合法的 XML:

<square width="100" />

在上面的例子中,"square" 被定义为带有 CDATA 类型的 "width" 属性的空元素。如果宽度没有被设定,其默认值为0 。

3.实体

         实体是用于定义引用普通文本或特殊字符的快捷方式的变量。

HTML 实体引用:"&nbsp;",这个“无折行空格”实体在HTML 中被用于在某个文档中插入一个额外的空格。

当文档被 XML 解析器解析时,实体就会被展开。

下面的实体在 XML 中被预定义:

实体引用

字符

&lt;

&gt;

&amp;

&

&quot;

"

&apos;

'

内部实体声明:

语法:

<!ENTITY实体名称 "实体的值">

DTD 例子:

<!ENTITY writer "BillGates">

<!ENTITY copyright "Copyright 具体的url">

XML中使用实体:

<author>&writer;&copyright;</author>注释: 一个实体由三部分构成: 一个和号 (&),一个实体名称, 以及一个分号 (;)。

外部实体声明:

<!ENTITY 实体名称 SYSTEM "URI/URL">

如:<!ENTITY writer SYSTEM"http://www.w3school.com.cn/dtd/entities.dtd">

XML中使用实体:

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

4.PCDATA

PCDATA 的意思是被解析的字符数据(parsedcharacter data)。

可把字符数据想象为 XML 元素的开始标签与结束标签之间的文本。

PCDATA 是会被解析器解析的文本。这些文本将被解析器检查实体以及标记。

文本中的标签会被当作标记来处理,而实体会被展开。

不过,被解析的字符数据不应当包含任何 &、< 或者 > 字符;需要使用 &amp;、&lt; 以及 &gt; 实体来分别替换它们。

5.CDATA

CDATA 的意思是字符数据(characterdata)。

CDATA 是不会被解析器解析的文本。在这些文本中的标签不会被当作标记来对待,其中的实体也不会被展开。

使用 DTD的优缺点

优点:通过 DTD,您的每一个 XML 文件均可携带一个有关其自身格式的描述。

通过 DTD,独立的团体可一致地使用某个标准的 DTD 来交换数据。

而您的应用程序也可使用某个标准的 DTD 来验证从外部接收到的数据。

您还可以使用 DTD 来验证您自身的数据。

缺点:DTD有自己的特殊语法,其本身不是XML文档;DTD只提供了有限的数据类型,用户无法自定义类型;DTD不支持域名机制。

当解析XML文档时,开启校验,如果XML中的内容与文档定义中的不符,就会抛出异常,如:

Error:URI=file:///I:/IOTEST/test.xml Line=8:元素类型 "description"不能声明多次。

Error:URI=file:///I:/IOTEST/test.xml Line=13:元素类型为 "country"的内容不完整,它必须匹配"(name,provinceList,description?)"

Error:URI=file:///I:/IOTEST/test.xml Line=16:元素类型为 "country"的内容不完整,它必须匹配"(name,provinceList,description?)"

Error: URI=file:///I:/IOTEST/test.xmlLine=17: 元素类型为 "countries" 的内容必须匹配 "(country)"

解析的XML文档内容为:

<?xml version="1.0"encoding="UTF-8"?><!DOCTYPE countries [<!ELEMENT countries (country)><!ELEMENT country(name,provinceList,description?)><!ELEMENT description  (#PCDATA)><!ELEMENT provinceList(province+,description?)><!ELEMENT province (name , city+ ,description?)><!ELEMENT description  (content)>]><countries>         <country></country>         <country></country></countries>

根据web-app.dtd文档分析web.xml中常见的错误

web-app_2_3.dtd文档中规定了web.xml文档中可以出现的元素及其可以包含的属性,以及各元素属性在文档中的排列顺序,web.xml文档的内容必须严格符合其定义。不然就会报错。例如错误提示:

The content ofelement type "web-app" must match"(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,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*)".

上面的错误就是由于元素排列顺序不正确引起的,编辑器将dtd文档中的对应部分提取出来,提示需要符合指定格式。

在web-app_2_3.dtd中共定义了77个元素,77个属性,是与元素一一对应的id,都是可选的。下面贴出来web-app_2_3.dtd中关于web.xml元素的定义:

<!ELEMENT web-app(icon?, display-name?, description?, distributable?,context-param*, filter*, filter-mapping*,listener*, 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 auth-constraint(description?, role-name*)><!ELEMENT auth-method(#PCDATA)><!ELEMENT context-param(param-name, param-value, description?)><!ELEMENT description(#PCDATA)><!ELEMENT display-name(#PCDATA)><!ELEMENT distributableEMPTY><!ELEMENT ejb-link(#PCDATA)><!ELEMENT ejb-local-ref(description?, ejb-ref-name, ejb-ref-type,      local-home,local, ejb-link?)><!ELEMENT ejb-ref(description?, ejb-ref-name, ejb-ref-type,      home,remote, ejb-link?)><!ELEMENT ejb-ref-name(#PCDATA)><!ELEMENT ejb-ref-type(#PCDATA)><!ELEMENT env-entry(description?, env-entry-name, env-entry-value?,env-entry-type)><!ELEMENT env-entry-name(#PCDATA)><!ELEMENT env-entry-type(#PCDATA)><!ELEMENT env-entry-value(#PCDATA)><!ELEMENT error-code(#PCDATA)><!ELEMENT error-page((error-code | exception-type), location)><!ELEMENT exception-type(#PCDATA)><!ELEMENT extension(#PCDATA)><!ELEMENT filter(icon?, filter-name, display-name?, description?,filter-class, init-param*)><!ELEMENT filter-class(#PCDATA)><!ELEMENT filter-mapping(filter-name, (url-pattern | servlet-name))><!ELEMENT filter-name(#PCDATA)><!ELEMENT form-error-page(#PCDATA)><!ELEMENT form-login-config(form-login-page, form-error-page)><!ELEMENT form-login-page(#PCDATA)><!ELEMENT home (#PCDATA)><!ELEMENT http-method(#PCDATA)><!ELEMENT icon(small-icon?, large-icon?)><!ELEMENT init-param(param-name, param-value, description?)><!ELEMENT jsp-file(#PCDATA)><!ELEMENT large-icon(#PCDATA)><!ELEMENT listener(listener-class)><!ELEMENT listener-class(#PCDATA)><!ELEMENT load-on-startup(#PCDATA)><!ELEMENT local (#PCDATA)><!ELEMENT local-home(#PCDATA)><!ELEMENT location(#PCDATA)><!ELEMENT login-config(auth-method?, realm-name?, form-login-config?)><!ELEMENT mime-mapping(extension, mime-type)><!ELEMENT mime-type(#PCDATA)><!ELEMENT param-name(#PCDATA)><!ELEMENT param-value(#PCDATA)><!ELEMENT realm-name(#PCDATA)><!ELEMENT remote (#PCDATA)><!ELEMENT res-auth(#PCDATA)><!ELEMENT res-ref-name(#PCDATA)><!ELEMENT res-sharing-scope(#PCDATA)><!ELEMENT res-type(#PCDATA)><!ELEMENT resource-env-ref(description?, resource-env-ref-name,      resource-env-ref-type)><!ELEMENT resource-env-ref-name(#PCDATA)><!ELEMENT resource-env-ref-type(#PCDATA)><!ELEMENT resource-ref(description?, res-ref-name, res-type, res-auth,      res-sharing-scope?)><!ELEMENT role-link(#PCDATA)><!ELEMENT role-name(#PCDATA)><!ELEMENT run-as(description?, role-name)><!ELEMENT security-constraint(display-name?, web-resource-collection+,auth-constraint?, user-data-constraint?)><!ELEMENT security-role(description?, role-name)><!ELEMENT security-role-ref(description?, role-name, role-link?)><!ELEMENT servlet(icon?, servlet-name, display-name?, description?,(servlet-class|jsp-file), init-param*,load-on-startup?, run-as?, security-role-ref*)><!ELEMENT servlet-class(#PCDATA)><!ELEMENT servlet-mapping(servlet-name, url-pattern)><!ELEMENT servlet-name(#PCDATA)><!ELEMENT session-config(session-timeout?)><!ELEMENT session-timeout(#PCDATA)><!ELEMENT small-icon(#PCDATA)><!ELEMENT taglib(taglib-uri, taglib-location)><!ELEMENT taglib-location(#PCDATA)><!ELEMENT taglib-uri(#PCDATA)><!ELEMENT transport-guarantee(#PCDATA)><!ELEMENT url-pattern(#PCDATA)><!ELEMENT user-data-constraint(description?, transport-guarantee)><!ELEMENT web-resource-collection(web-resource-name, description?,url-pattern*, http-method*)><!ELEMENT web-resource-name(#PCDATA)><!ELEMENT welcome-file(#PCDATA)><!ELEMENT welcome-file-list(welcome-file+)>
上面的DTD中的第一个元素定义了web.xml的根元素web-app,其中可以包含的子元素都在()中进行了说明,出现的顺序就是在()中排列的顺序,可以尝试一下,在编写web.xml时,不使用规定的顺序,发现会提示上面例子中的错误。

根元素中常用的子元素可以粗略的总结这样的规律:按字母首字母进行排序。这只是一个粗略的总结,实际情况肯定是要根据DTD中的定义的。对照下面的表格继续解读:

符号

元素出现的次数

1或0次

*

任意次

+

>=1

无符号

1次

发现根元素的子元素有两种,一种是出现最多一次的描述性元素,另一种是可以出现任意多次的项目配置性元素。

在上面出现的元素中:

<web-app>:Web应用的根元素。

<display-name>:Web应用的名字。

<descruption>:对Web应用的描述。

<filter>:定义过滤器。

<filter-mapping>:为过滤器指定URL映射。

<servlet>:定义Servlet。

<servlet-mapping>:为Servlet指定URL映射。

<listener>:配置监听器。

<session-config>:配置HTTP会话。

<welcome-file-list>:设置Web应用的Welcome文件清单。

<taglib>:声明引用的标签库。

<resource-ref>:声明引用的JNDI资源。

<security-constraint>:配置安全约束。

<login-config>:配置安全验证登录界面。

<security-role>:配置安全角色。

元素定义语句

解释

<!ELEMENT context-param (param-name, param-value, description?)>

context-param元素中有三个元素param-name, param-value, description。前两个元素必须出现且只能出现一次;description元素可以出现也可以只出现一次。

<!ELEMENT description (#PCDATA)>

description下没有子元素,其形式必须为< description >some text< description />,(#PCDATA)表示其子节点需要解析为值。

<!ELEMENT error-page ((error-code | exception-type), location)>

error-page元素表示在某个页面中发生错误时转向的页面。在其下只能有两个元素,第一个元素是error-code与exception-type二者之一,第二个元素是location元素。在DTD中(element1|element2|element3……)表示()中的元素只能出现其中的一个,且只能出现一次。

web-app_2_3.dtd中的其他内容现在就可以自己完全看懂了。

若在web.xml文件中出现了错误,错误的提示格式是:

The content of element type "dtd中定义的元素名" is incomplete, it must match "dtd中元素的定义格式"。接下来只要根据提示找到出现错误的元素,再根据该元素的DTD定义修改就可以了。大多数出现的错误就是顺序错误和元素个数错误,该出现的没有出现,不该出现的出现了。

 

 

 

0 0
原创粉丝点击