XML——XML文件约束之DTD详解
1.XML文件约束与DTD的简单介绍我们编写文档来约束一个XML文档的书写规范,这称之为XML约束。 常用的约束技术有:
DTD的基本概念:
DTD文件一般和XML文件配合使用,主要是为了约束XML文件。 XML文件引入DTD文件,这样XML可以自定义标签,但又受到DTD文件的约束。比如上一节使用XML描述一个班级的信息,如果我们给每一个学生定义一个 <?xml version="1.0" encoding="gb2312"?>
<class>
<stu id="001">
<name>杨过</name>
<sex>男</sex>
<age>20</age>
<面积>100</面积>
</stu>
</class>
1.1 DTD约束快速入门案例基本语法: <!ELEMENT 元素名 类型>
我们还以班级为例,编写如下DTD文件,myClass.dtd: <!ELEMENT 班级 (学生+)>
<!ELEMENT 学生 (名字,年龄,介绍)>
<!ELEMENT 名字 (#PCDATA)>
<!ELEMENT 年龄 (#PCDATA)>
<!ELEMENT 介绍 (#PCDATA)>
第一行表示根元素为班级,并且有学生这个子元素,子元素为1或者多个。 编写myClass.xml文件并引入DTD文件如下: <?xml version="1.0" encoding="utf-8"?>
<!--引入dtd文件,约束这个xml-->
<!DOCTYPE 班级 SYSTEM "myClass.dtd">
<班级>
<学生>
<名字>周小星</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生>
<名字>林晓</名字>
<年龄>25</年龄>
<介绍>是一个好学生</介绍>
</学生>
</班级>
引入中写的:SYSTEM,表示当前的DTD文件是本地的 这时候引入的DTD文件是没有产生作用的,如果我们在学生元素中添加子元素 <?xml version="1.0" encoding="utf-8"?>
<!--引入dtd文件,约束这个xml-->
<!DOCTYPE 班级 SYSTEM "myClass.dtd">
<班级>
<学生>
<名字>周小星</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
<面积>100平米</面积>
</学生>
<学生>
<名字>林晓</名字>
<年龄>25</年龄>
<介绍>是一个好学生</介绍>
</学生>
</班级>
我们需要编程校验XML文档的正确性。 IE5以上的浏览器内置了XML解析工具:Microsoft.XMLDOM,开发人员可以编写JavaScript代码,利用这个解析工具装载XML文件,并对XML文件进行DTD验证。 我们编写myXmlTools.html来对这个XML进行校验,如下: <html>
<head>
<!--自己编写一个简单的解析工具,去解析XML DTD是否配套-->
<script language="javascript"> // 创建xml文档解析器对象 var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); // 开启xml校验 xmldoc.validateOnParse = "true"; // 装载xml文档,即指定校验哪个XML文件 xmldoc.load("myClass.xml"); document.writeln("错误信息:"+xmldoc.parseError.reason+"<br>"); document.writeln("错误行号:"+xmldoc.parseError.line); </script>
</head>
<body>
</body>
</html>
用IE浏览器打开这个html文件,可以看到运行结果: 可以看到第9行正是我们添加的 2.DTD细节2.1 DTD文档的声明及引用1.内部DTD文档 <!DOCTYPE 根元素 [定义内容]>
2.外部DTD文档 引入外部的DTD文档分为两种: (1)当引用的DTD文件是本地文件的时候,用SYSTEM标识,并写上”DTD的文件路径”,如下: <!DOCTYPE 根元素 SYSTEM "DTD文件路径">
(2)如果引用的DTD文件是一个公共的文件时,采用PUBLIC标识,如下方式: <!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件的URL">
比如下例: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems,Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
2.2 DTD基本语法:<!ELEMENT NAME CONTENT>
其中:
2.3 DTD元素的组合类型:DTD中这样规定: <!ELEMENT 家庭(人+,家电*)>
这个DTD规定了家庭元素中可以有1到多个”人”这个子元素,也可以有0到多个”家电”这个子元素。其中的加号”+”和星号”*”的含义与正则表达式中的含义一致。 XML这样写: <家庭>
<人 名字="张晓明" 性别="男" 年龄="25"/>
<人 名字="李小钢" 性别="男" 年龄="36" 爱好="作个教育家和伟人"/>
<家电 名称="彩电" 数量="3"/>
</家庭>
关于组合类型,有下述的的修饰符可以使用:
2.4 属性定义DTD中属性的定义是这样的: <!ATTLIST 元素名称 属性名称 类型 属性特点 属性名称 类型 属性特点...... >
其中,属性的类型有下面5种:
属性的特点有如下4种:
比如,我们想在学生这个子元素上加上地址这个属性,而且这个属性是必须的,示例如下: <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE 班级 SYSTEM "myClass.dtd">
<班级>
<学生 地址="香港">
<名字>周小星</名字>
<年龄>23</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生 地址="澳门">
<名字>林晓</名字>
<年龄>25</年龄>
<介绍>是一个好学生</介绍>
</学生>
</班级>
这个时候相应的DTD文件也要更新,不然就会报错,如下: <!ELEMENT 班级 (学生+)>
<!ELEMENT 学生 (名字,介绍)>
<!ATTLIST 学生 地址 CDATA #REQUIRED >
<!ELEMENT 名字 (#PCDATA)>
<!ELEMENT 年龄 (#PCDATA)>
<!ELEMENT 介绍 (#PCDATA)>
2.4.1 对于属性类型的详细解释(1)属性类型-CDATA,表示属性值可以是任何字符(包括中文和数字) <!ATTLIST 木偶 姓名 CDATA #REQUIRED >
<木偶 姓名="匹诺曹"/>
<木偶 姓名="PiNuocao"/>
<木偶 姓名="123"/>
(2)属性类型-ID,表明该属性的取值必须是唯一的,但是属性的值不能是以数字开头! <!ELEMENT 公司职员 ANY>
<!ATTLIST 公司职员 编号 ID #REQUIRED 姓名 CDATA #REQUIRED >
<公司职员 编号="Z001" 姓名="张三"/>
<公司职员 编号="Z002" 姓名="李思"/>
(3)属性类型-IDREF/IDREFS <!ELEMENT 家庭(人+)>
<!ELEMENT 人 EMPTY>
<!ATTLIST 人 relID ID #REQUIRED paraentID IDREFS #IMPLIED name CDATA #REQUIRED >
<家庭>
<人 relID="P_1" name="爸爸"/>
<人 relID="P_2" name="妈妈"/>
<人 relID="P_3" parentID="P_1 P_2" name="儿子"/>
</家庭>
(4)属性类型-Enumerated,事先定义好一些值,属性的值必须在所列出的值的范围内。 <!ATTLIST person 婚姻状态 (single|married|divorced|widowed) #IMPLIED >
<!ATTLIST person 性别 (男|女) #REQUIRED >
(5)属性类型-ENTITY,实体 实体定义: ①引用实体:
<!ENTITY 实体名称 "实体内容">
举例如下: <!ENTITY copyright "I am a programmer">
....
©right;
②参数实体:
<!ENTITY % 实体名称 "实体内容">
举例: <!ENTITY % TAG_NAME "姓名|EMAIL|电话|地址">
<!ELEMENT 个人信息 (%TAG_NAME;|生日)>
<!ELEMENT 客户信息 (%TAG_NAME;|公司名)>
3.DTD实际案例学习DTD的目标在于: 下面我们看一个案例,下述的DTD文件是从W3School在线教程中的DTD案例中拿过来的,细看每一行,我们都应该能够看得懂。 <!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)>
然后我们可以根据该DTD编写如下最简单的XML文件: <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE CATALOG SYSTEM "product.dtd">
<CATALOG>
<PRODUCT NAME="康帅傅矿泉水" CATEGORY="Table" PARTNUM="12" PLANT="Chicago">
<SPECIFICATIONS WEIGHT="20" POWER="18">这里是细节</SPECIFICATIONS>
<PRICE>25</PRICE>
<PRICE>28</PRICE>
</PRODUCT>
</CATALOG>
然后我们用Microsoft.XMLDOM校验该XML,会发现没有任何错误。但是要注意编码。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- c# – WPF全屏最大化
- Error:(37) Error parsing XML: not well-formed (invalid
- ruby-on-rails – RabbitMQ 3.5.6无法与任何配置的主机建立
- Networker 8.1异机恢复Oracle 11gR2
- 【Java编程】SAX XML Parser解析、生成XML文件
- c# – PDF在IE中隐藏Jquery Modal
- 解析XML Libxmljs(Node.js)
- ruby-on-rails – 如何在rails_admin的列表操作中显示图像?
- 如何在postgresql中使用递归查询连接字段值?
- Flex mouseEnabled和mouseChildren的区别