XML学习笔记(二):XML规范:DTD详解
一、DTD:文档类型定义 1、简介: 1)DTD 可定义合法的XML文档构建模块。它使用一系列合法的元素来定义文档的结构。 2)DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用。
2、内部申明:DOCTYPE 1)语法:假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中:
<!DOCTYPE 根元素 [元素声明]> 2)例如:带有 DTD 的 XML 文档实例(请在 IE5 以及更高的版本打开,并选择查看源代码):
<?xml version="1.0"?> <!DOCTYPE request [ <!ELEMENT request (appnt,insured,product,service)> <!ELEMENT appnt (#PCDATA)> <!ELEMENT insured (#PCDATA)> <!ELEMENT product (#PCDATA)> <!ELEMENT service (#PCDATA)> ]> <request> <appnt>George</appnt> <insured>John</insured> <product>Reminder</product> <service>Don't forget the meeting!</service> </request> 以上 DTD 解释如下: !DOCTYPE request (第二行)定义此文档是 request 类型的文档。 !ELEMENT request (第三行)定义 request 元素有四个元素:"appnt、insured、product、service" !ELEMENT appnt (第四行)定义 appnt 元素为 "#PCDATA" 类型 !ELEMENT insured (第五行)定义 insured 元素为 "#PCDATA" 类型 !ELEMENT product (第六行)定义 product 元素为 "#PCDATA" 类型 !ELEMENT service (第七行)定义 service 元素为 "#PCDATA" 类型 3、外部申明: 1)语法1: <!DOCTYPE 根元素 SYSTEM "文件名"> 2)例如:这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD: <?xml version="1.0"?> <!DOCTYPE request SYSTEM "request.dtd"> <request> <appnt>George</appnt> <insured>John</insured> <product>Reminder</product> <service>Don't forget the meeting!</service> </request>
<!ELEMENT request (appnt,service)> <!ELEMENT appnt (#PCDATA)> <!ELEMENT insured (#PCDATA)> <!ELEMENT product (#PCDATA)> <!ELEMENT service (#PCDATA)> 3)语法2:如果引用的外部文件时一个公共的文件时, <!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件的URL"> 例子: <?xml version="1.0"?> <!DOCTYPE request PUBLIC "request.dtd" "http://java.sun.com"> <request> <appnt>George</appnt> <insured>John</insured> <product>Reminder</product> <service>Don't forget the meeting!</service> </request> 4、XML 构建模块 所有的 XML 文档均由以下简单的构建模块构成:
3)实体:即定义一个变量指向一个内容。分为引用实体和参数实体。
5)CDATA:是不会被解析器解析的文本
5、DTD-元素:元素的定义规范如下:
在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法: <!ELEMENT 元素名称 类别> 或者 <!ELEMENT 元素名称 (元素内容)>
元素名称后面可以 类型或者内容,内容需要用()括起来,用“,”、“|”、“*”、“?”、“+”等分开表示,顺序必须保持一致。 简单介绍一些具体的语法实例: 1)空元素:空元素通过类别关键词EMPTY进行声明: <!ELEMENT 元素名称 EMPTY> 例子: <!ELEMENT person EMPTY> XML例子: <person /> 2)只有 PCDATA 的元素:通过圆括号中的 #PCDATA 进行声明: <!ELEMENT 元素名称 (#PCDATA)> 例子: <!ELEMENT from (#PCDATA)> XML例子: <person>SooZhou</person> 3)带有任何内容的元素: <!ELEMENT 元素名称 ANY> 例子: <!ELEMENT note ANY> 4)带有子元素(序列)的元素: <!ELEMENT 元素名称 (子元素名称 1)> 或者 <!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)> 例子: <!ELEMENT request(to,from,heading,body)> 当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的声明中,子元素也必须被声明,同时子元素也可拥有子元素。 "request" 元素的完整声明是: <!ELEMENT request (to,body)> <!ELEMENT to (#PCDATA)> <!ELEMENT from (#PCDATA)> <!ELEMENT heading (#PCDATA)> <!ELEMENT body (#PCDATA)>
5)声明只出现一次的元素 <!ELEMENT 元素名称 (子元素名称)> 例子: <!ELEMENT note (message)> 上面的例子声明了:message 子元素必须出现一次,并且必须只在 "note" 元素中出现一次。
6)声明最少出现一次的元素: “ + ” <!ELEMENT 元素名称 (子元素名称+)> 例子: <!ELEMENT note (message+)> 上面的例子中的加号声明了:message 子元素必须在 "note" 元素内出现至少一次。
7)其他: 声明出现零次或多次的元素 “*” <!ELEMENT 元素名称 (子元素名称*)> 例子: <!ELEMENT note (message*)> 上面的例子中的星号声明了:子元素 message 可在 "note" 元素内出现零次或多次。 声明出现零次或一次的元素 “?” <!ELEMENT 元素名称 (子元素名称?)> 例子: <!ELEMENT note (message?)> 上面的例子中的问号声明了:子元素 message 可在 "note" 元素内出现零次或一次。 声明“非.../既...”类型的内容 例子: <!ELEMENT note (to,header,(message|body))> 上面的例子声明了:"note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,以及非 "message" 元素既 "body" 元素。 声明混合型的内容 例子: <!ELEMENT note (#PCDATA|to|from|header|message)*> 上面的例子声明了:"note" 元素可包含出现零次或多次的 PCDATA、"to"、"from"、"header" 或者 "message"。 6、DTD - 属性 Attlist关键字 在 DTD 中,属性通过 ATTLIST 声明来进行声明。
1)语法: <!ATTLIST 元素名称 属性名称 属性类型 默认值>
DTD 实例: <!ATTLIST payment type CDATA "check"> XML 实例: <payment type="check" /> 2)属性的类型和值:
例如:规定一个默认的属性值: DTD: <!ELEMENT square EMPTY> <!ATTLIST square width CDATA "0"> 合法的 XML: <square width="100" /> 分析:"square" 被定义为带有 CDATA 类型的 "width" 属性的空元素。如果宽度没有被设定,其默认值为0 。
①、#REQUIRED——属性值是必需的
②、#IMPLIED——属性不是必需的
③、#FIXED value——属性值是固定的
④、列举属性:
7、DTD - 实体:Entity 关键字 实体是用于定义引用普通文本或特殊字符的快捷方式的变量。分为引用实体和参数实体 第一、引用实体是对实体的引用。实体可在内部或外部进行声明。
1)内部申明
2)外部申明:使用SYSTEM 关键字
第二、参数实体。 被DTD文件自身使用。 1)语法:使用 % <!ENTITY % 实体名称 "实体的值">
8、自己试着去分析Struts的DTD规范。struts-2.3.dtd文件代码如下
<?xml version="1.0" encoding="UTF-8"?> <!-- /* * $Id: struts-2.0.dtd 651946 2008-04-27 13:41:38Z apetrelli $ * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License,Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an * "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND,either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ --> <!-- START SNIPPET: strutsDtd --> <!-- Struts configuration DTD. Use the following DOCTYPE <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> --> <!-- ***************** 以上为注释******************** --> <!ELEMENT struts ((package|include|bean|constant)*,unknown-handler-stack?)> <!ATTLIST struts order CDATA #IMPLIED > <!-- 1、ELEMENT:定义struts元素的子元素: ()内的为元素的名称: 1)、(package|include|bean|constant)*:使用 “|” ,为四个元素必须有一个, 且使用“*”,表示可以出现0次或多次 2)、unknown-handler-stack? :表示这个名字的标签可以出现0次或1次 2、ATTLIST:定义struts元素的属性: 1)、属性名称为 order, 2)、类型为 CDATA ,不会被解析的文本(即字符串) 3)、#IMPLIED,这个属性不是必须的 --> <!ELEMENT package (result-types?,interceptors?,default-interceptor-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*)> <!ATTLIST package name CDATA #REQUIRED extends CDATA #IMPLIED namespace CDATA #IMPLIED abstract CDATA #IMPLIED strict-method-invocation CDATA #IMPLIED externalReferenceResolver NMTOKEN #IMPLIED > <!-- 1、ELEMENT:定义package元素的子元素: ()内的为元素的名称: 1)、result-types? :result-types 元素可出现0或1次 2)、action* :action标签可以出现0次或多次 2、ATTLIST:定义package元素的属性: 1)、定义了6个属性,名称分别为 name、extends、namespace、abstract、 strict-method-invocation、externalReferenceResolver 2)、类型为 CDATA ,不会被解析的文本(即字符串) 3)、属性externalReferenceResolver,的类型为NMTOKEN,即其他合法的xml名称。可以自定义一个xml 4)、只有name属性是必须的,其选择即可。 --> <!ELEMENT result-types (result-type+)> <!ELEMENT result-type (param*)> <!ATTLIST result-type name CDATA #REQUIRED class CDATA #REQUIRED default (true|false) "false" > <!-- 1、ELEMENT:定义result-types元素的子元素: ()内的为元素的名称: 1)、result-type+ :result-type 元素至少出现一次,即一定要有一个 2、ELEMENT:定义result-type元素的子元素: ()内的为元素的名称: 1)、param* :param元素可以有0次或多次 3、ATTLIST:定义result-type元素的属性: 1)、定义了3个属性,名称分别为 name、class、default 2)、类型为 CDATA ,不会被解析的文本(即字符串) 3)、属性default,的类型为枚举的其中一个,这边可以选择true或false,默认值为false 4)、name和class属性是必须的 --> <!ELEMENT interceptors (interceptor|interceptor-stack)+> <!ELEMENT interceptor (param*)> <!ATTLIST interceptor name CDATA #REQUIRED class CDATA #REQUIRED > <!ELEMENT interceptor-stack (interceptor-ref*)> <!ATTLIST interceptor-stack name CDATA #REQUIRED > <!ELEMENT interceptor-ref (param*)> <!ATTLIST interceptor-ref name CDATA #REQUIRED > <!ELEMENT default-interceptor-ref (#PCDATA)> <!ATTLIST default-interceptor-ref name CDATA #REQUIRED > <!ELEMENT default-action-ref (#PCDATA)> <!ATTLIST default-action-ref name CDATA #REQUIRED > <!ELEMENT default-class-ref (#PCDATA)> <!ATTLIST default-class-ref class CDATA #REQUIRED > <!ELEMENT global-results (result+)> <!ELEMENT global-exception-mappings (exception-mapping+)> <!ELEMENT action ((param|result|interceptor-ref|exception-mapping)*,allowed-methods?)> <!ATTLIST action name CDATA #REQUIRED class CDATA #IMPLIED method CDATA #IMPLIED converter CDATA #IMPLIED > <!ELEMENT param (#PCDATA)> <!ATTLIST param name CDATA #REQUIRED > <!ELEMENT result (#PCDATA|param)*> <!ATTLIST result name CDATA #IMPLIED type CDATA #IMPLIED > <!ELEMENT exception-mapping (#PCDATA|param)*> <!ATTLIST exception-mapping name CDATA #IMPLIED exception CDATA #REQUIRED result CDATA #REQUIRED > <!ELEMENT allowed-methods (#PCDATA)> <!ELEMENT include (#PCDATA)> <!ATTLIST include file CDATA #REQUIRED > <!ELEMENT bean (#PCDATA)> <!ATTLIST bean type CDATA #IMPLIED name CDATA #IMPLIED class CDATA #REQUIRED scope CDATA #IMPLIED static CDATA #IMPLIED optional CDATA #IMPLIED > <!ELEMENT constant (#PCDATA)> <!ATTLIST constant name CDATA #REQUIRED value CDATA #REQUIRED > <!ELEMENT unknown-handler-stack (unknown-handler-ref*)> <!ELEMENT unknown-handler-ref (#PCDATA)> <!ATTLIST unknown-handler-ref name CDATA #REQUIRED > <!-- END SNIPPET: strutsDtd --> 9、根据DTD,自己写XML文件。 1)DTD为如下文件: <!DOCTYPE CATALOG [ <!ENTITY AUTHOR "John Doe"> <!ENTITY COMPANY "JD Power Tools,Inc."> <!ENTITY EMAIL "jd@jd-tools.com"> <!ELEMENT CATALOG (PRODUCT+)> <!ELEMENT PRODUCT (SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)> <!ATTLIST PRODUCT NAME CDATA #IMPLIED CATEGORY (HandTool|Table|Shop-Professional) "HandTool" PARTNUM CDATA #IMPLIED PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago" INVENTORY (InStock|Backordered|Discontinued) "InStock"> <!ELEMENT SPECIFICATIONS (#PCDATA)> <!ATTLIST SPECIFICATIONS WEIGHT CDATA #IMPLIED POWER CDATA #IMPLIED> <!ELEMENT OPTIONS (#PCDATA)> <!ATTLIST OPTIONS FINISH (Metal|Polished|Matte) "Matte" ADAPTER (Included|Optional|NotApplicable) "Included" CASE (HardShell|Soft|NotApplicable) "HardShell"> <!ELEMENT PRICE (#PCDATA)> <!ATTLIST PRICE MSRP CDATA #IMPLIED WHOLESALE CDATA #IMPLIED STREET CDATA #IMPLIED SHIPPING CDATA #IMPLIED> <!ELEMENT NOTES (#PCDATA)> ]> 2)自己写的XML如下: <?xml version="1.0" encoding="UTF-8"?> <!-- DTD start--> <!DOCTYPE CATALOG [ <!ENTITY AUTHOR "John Doe"> <!ENTITY COMPANY "JD Power Tools,Inc."> <!ENTITY EMAIL "jd@jd-tools.com"> <!ELEMENT CATALOG (PRODUCT+)> <!ELEMENT PRODUCT (SPECIFICATIONS+,NOTES?)> <!ATTLIST PRODUCT NAME CDATA #IMPLIED CATEGORY (HandTool|Table|Shop-Professional) "HandTool" PARTNUM CDATA #IMPLIED PLANT (Pittsburgh|Milwaukee|Chicago) "Chicago" INVENTORY (InStock|Backordered|Discontinued) "InStock"> <!ELEMENT SPECIFICATIONS (#PCDATA)> <!ATTLIST SPECIFICATIONS WEIGHT CDATA #IMPLIED POWER CDATA #IMPLIED> <!ELEMENT OPTIONS (#PCDATA)> <!ATTLIST OPTIONS FINISH (Metal|Polished|Matte) "Matte" ADAPTER (Included|Optional|NotApplicable) "Included" CASE (HardShell|Soft|NotApplicable) "HardShell"> <!ELEMENT PRICE (#PCDATA)> <!ATTLIST PRICE MSRP CDATA #IMPLIED WHOLESALE CDATA #IMPLIED STREET CDATA #IMPLIED SHIPPING CDATA #IMPLIED> <!ELEMENT NOTES (#PCDATA)> ]> <!-- DTD end--> <!-- 分析: 1、实体:定义三个实体 1)AUTHOR、COMPANY、EMAIL 2、PRODUCT元素: 1)PRODUCT+ 至少出现一次 2)内部有元素:SPECIFICATIONS+(一定有一个),NOTES?(0次或1次) 2)属性:NAME、CATEGORY、PARTNUM、PLANT、INVENTORY 都不是必须的 3、SPECIFICATIONS元素:一定有一个 1)内容:PCDATA,可解析。不能出现 < 等 2)属性:都是可选属性,WEIGHT,POWER 4、OPTIONS元素: 1)内容:PCDATA 2)属性:可选属性,FINISH、ADAPTER、CASE。 3)属性类型都是枚举,固定有默认值 5、PRICE元素: 1)内容:PCDATA 2)属性:可选属性,MSRP、WHOLESALE、STREET、SHIPPING 6、NOTES元素 --> <CATALOG> <PRODUCT NAME="牙膏"> <SPECIFICATIONS WEIGHT="" POWER="">AAAA</SPECIFICATIONS> <OPTIONS FINISH="Polished" ADAPTER ="Optional" CASE="NotApplicable">BBBB</OPTIONS> <PRICE MSRP="" WHOLESALE="" STREET="" SHIPPING="">CCCC</PRICE> <NOTES>DDDDD</NOTES> </PRODUCT> <PRODUCT NAME="牙膏"> <SPECIFICATIONS WEIGHT="" POWER="">AAAA</SPECIFICATIONS> <OPTIONS FINISH="Polished" ADAPTER ="Optional" CASE="NotApplicable">BBBB</OPTIONS> <PRICE MSRP="" WHOLESALE="" STREET="" SHIPPING="">CCCC</PRICE> <NOTES>DDDDD</NOTES> </PRODUCT> </CATALOG> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |