【0】README

0.1)本文文字描述转自 core java volume 2 , 旨在理解 XML——文档类型定义(DTD-Document Type Definition) 的基础知识;
0.2) for source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter2/ParseXMLTest.java
0.3) 为什么使用 DTD: 参见 http://blog.csdn.net/pacosonswjtu/article/details/50588471


【1】DTD相关

1)提供DTD的方式有多种,可以将其纳入到 XML文档中:

<?xml version="1.0">
<!DOCTYPE configuration [<!ELEMENT configuration ...>more rules...
]>

2)正如你所看到的,这些规则被纳入到了 DOCTYPE声明中, 该代码块使用 […] 来限定其界限;文档类型必须匹配根元素的名字,比如 荔枝中的configuration;
3)在XML 文档内部使用 DTD 不是很普遍,因为DTD会使文件长度变得很长,把DTD存储在外面更具有意义; (干货——在XML 文档内部使用 DTD 不是很普遍,因为DTD会使文件长度变得很长,把DTD存储在外面,这也是引入SYSTEM声明的原因)

  • 3.1)SYSTEM声明可以用来实现这个目标,你可以指定一个包含DTD的URL,如:
<!DOCTYPE configuration SYSTEM "config.dtd">或者:
<!DOCTYPE configuration SYSTEM "http://myserver.com/config.dtd">
  • Warning)

    • w1)如果你使用 的是 DTD 的相对URL(比如 config.dtd),那么要给解析器一个 File 或 URL 对象,而不是 InputStream;(干货——如果使用相对URL定位DTD)
    • w2)如果必须从一个输入流来解析,请提供一个实体解析器;

4)最后,有一个来源于 SGML 的用于识别DTD的机制:

<!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2 //EN""http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">

Attention)

  • A1)如果你使用的是DOM 解析器, 并且想支持 PUBLIC标识符,请调用 DocumentBuilder 类的 setEntityResolver 方法来安装 EntityResolver 接口的某个实现类的一个对象。该接口只有一个方法:resolveEntity;
  • A2) 下面是一个典型实现的代码框架:
class MyEntityResolver implements EntityResolver
{public InputSource resolveEntity(String publicId, String systemId){if(publicId.equals(a  known Id))return new InputSource(DTD data);elseretunr null;}
}
你可以从 InputStream, Reader 或字符串构建输入源;

5) 现在你知道了 解析器怎样定位 DTD了,下面,看看不同类型的规则:

  • 5.1)ELEMENT 规则:用于指定某个 元素可以拥有什么样的子元素;可以指定一个正则表达式,如下表所示: (干货——ELEMENT 规则和正则表达式结合起来)

  • 5.2) 下面是一些简单而典型的荔枝。 下面的规则声明了 menu 元素包含0个或多个item 元素:

<!ELEMENT font (name, size)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT size (#PCDATA)>

Attention)

  • A1) PCDATA = parsed char data, 表示已解析的字符数据; (干货——PCDATA定义 not CDATA 定义)
  • A2)数据是已解析的,因为 解析器通过寻找表示一个新标签起始的 < 字符或 表示一个实体起始的 & 字符, 而解释了这些文本字符串;

  • 5.4) 元素的规格说明可以包含 嵌套的和复制的正则表达式, 如, 下面是一个描述了本书中每一章的结构的规则: (干货——元素的规格说明可以包含 嵌套的和复制的正则表达式)

<!ELEMENT chapter (intro,(heading,(para|image|table|noe)+)+)>
每章都以简洁开头, 其后是一个或多个小节, 每个小节有一个标题和一个或多个段落,图片,表格或说明构成;
  • 5.5)有一种常见的case 是: 不能把规则定义得像你希望的那样灵活。当一个元素可以包含文本时,那么就只有两种合法的cases:

    • case1)要么元素只包含文本, 比如 <!ELEMENT name (#PCDATA)>
    • case2)要么元素只包含任意顺序的文本和标签的组合, 比如 <!ELEMENT para (#PCDATA|em|strong|code)*>
  • 5.6)指定其他包含 #PCDATA 规则的类型都是不合法的。如,以下规则是非法的:
<!ELEMENT captionedImage (image, #PCDATA)> , 必须重写一个规则,以引入另一个 caption 元素或 允许 使用 image 元素或文本的组合;
  • 5.6.1)这种限制简化了XML 解析器在解析混合式内容(标签和文本的混合)时的工作。因为在允许混合式内容时难免失控, 所以最好在设计 dtd时, 让其中所有的元素要么包含 其中元素,要么只包含文本;
  • 5.7) 还可以指定描述合法的元素属性的规则, 通用语法为: (干货——还可以指定描述合法的元素属性的规则)
    <!ATTLIST element attribute type default>

  • 5.7.1)下面是两个典型的属性规格说明:

<!ATTLIST font style (plain|bold|italic|bold-italic) "plain">
<!ATTLIST size unit CDATA #IMPLIED>
  • 对上述规格的分析(Analysis):

    • A1)第一个规格说明: 描述了font元素的style 属性, 它有4个合法的属性值, 默认值是 plain;
    • A2)第二个规则说明: 表示 size 元素的unit 属性 可以包含任意字符数据序列;
  • 5.8) 表2-2 显示了合法的属性类型, 表2-3 显示了属性默认值 的语法: (干货——CDATA定义)

Attention)

  • A1)一般情况下,我们推荐用元素而非属性来描述数据;
  • A2)属性有一个不可否认的优点: 那就是解析器能够校验取值是否合法,

6)CDATA属性值的处理与你前面看到的处理 #PCDATA有着微妙的差别: 并且与 < ![CDATA[...]]> 部分没有多大关系。 属性值首先被规范化, 也就是说, 解析器要处理对字符和实体的引用, 并且要用空格来替换空白字符;

  • 6.1)NMTOKEN(即名字标记)与 CDATA相似: 但是大多数非字母数字字符和内部的空白字符是不允许使用的, 而且解析器会删除起始和结尾的空白字符。NMTOKENS 是一个以空白字符分隔的名字标记列表;
  • 6.2) 属性类型介绍:
    • 6.2.1)ID: ID 结构是有用的, ID 是在文档中唯一的名字标记,解析器会检查其唯一性;
    • 6.2.2)IDREF: IDREF 是对同一个文档中 已存在的ID的应用;解析器也会对它进行检查;
    • 6.2.3)IDREFS: IDREFS 是以空白字符分割的 ID 引用的列表;
  • 6.3)ENTITY 属性值: 将引用一个 “未解析的外部实体”, 这是从 SGML将那里沿用下来的, 在实际应用中很少见;
  • 6.4)DTD 也可以定义实体,或定义解析过程中被替换的缩写。 (干货——DTD 也可以定义实体, 而其他地方的文本可以包含对这个实体的引用)
    • 6.4.1)看个荔枝:
<!ENTITY back.label "Back">
其他地方的文本可以包含对这个实体的引用,如: <menuitem label = "&back.label; "/>

7)Conclusion: 这样,我们就结束了对 DTD 的介绍了。你已经知道如何 使用 DTD了;你可以配置你的解析器以充分利用他们; (干货——如何配置XML解析器)

  • C1)首先,通知文档生成工程打开验证特性:
    factory.setValidating(true);
  • C2)这样, 该工厂生成的所有文档生成器都将根据DTD 来验证他们的输入。验证的最大好处是可以忽略元素内容的空白字符, 如,考虑如下代码:
<font><name>a</name><size>a</size>
</font>
  • C3)一个不进行验证的解析器会报告 font, name 和 size 元素之间的空白字符, 因为它无法知道 font 的子元素是: (name, size) (#PCDATA, name, size) * 还是 ANY
  • C4)一旦 DTD 指定了子元素是 (name, size), 解析器就知道他们之间的空白字符不是文本。调用下面的代码:
    factory.setIgnoringElementContentWhitespace(true); (干货——将dtd绑定到xml后,必须进行设置setIgnoringElementContentWhitespace)
    这样, 生成器就不会报告文本节点中的空白字符, 这意味着, 你可以依赖 font 节点只有2个子元素的事实。
  • C5)你只需要 通过如下代码访问第一个和第二个元素:
Element e1 = (Element) children.item(0);
Element e1 = (Element) children.item(1);


  • C6)这就是 DTD 如此有用的原因。 (干货——这就是 DTD 如此有用的原因)
  • C7) 当解析器报告错误的时候, 应用程序希望对该错误执行某些操作; (干货——当解析器报告错误的时候, 应用程序希望对该错误执行某些操作)
    • C7.1)在验证时, 应该安装一个 错误处理器,这需要提供一个实现了 ErrorHandler 接口的对象,这个接口有3个方法:
void warning(SAXParseException exception)
void error(SAXParseException exception)
void fatalError(SAXParseException exception)
可以通过 DocumentBuilder 类的  setErrorHandler 方法来安装 错误处理器:
builder.setErrorHandler(handler);

XML——文档类型定义(DTD-Document Type Definition)相关推荐

  1. XML文档类型定义DTD

    DTD概述 DTD用来定义XML文档的结构,它包含一系列规则说明,以确保XML文档的一致性和有效性 DTD定义了XML文档可用的词汇(元素和属性的名称)和结构: 元素名称,包括根元素 元素的属性及属性 ...

  2. XML--- XML文档类型定义(DTD)

    **定义:**DTD定义了文档的逻辑结构,规定了文档中所使用的元素.实体.元素的属性.元素与实体之间的关系.其作用主要表现在以下几个方面. (1) 使用DTD可以提供一种统一的格式.XML的可扩展性为 ...

  3. XML之文档类型定义和合法性(转)

    来至:liang--liang博客:http://www.cnblogs.com/liang--liang/archive/2008/01/15/1039277.html 好牛 XML被作为一种元标记 ...

  4. DTD(文档类型定义)概述

    DTD(文档类型定义)的作用是定义 XML 文档的合法构建模块.DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用. DTD 简介 文档类型定义(DTD)可定义合法的XML文档构建模块.它 ...

  5. 前端:HTML5/36/HTML5简介,文档类型定义,网页字符集,页面结构标记,文章相关的标记,其它标记,音频标记,视频标记,表单中新增的属性,表单input元素type属性的值

    HTML5简介 HTML5是新一代的HTML: HTML5目前主要应用在手机端,在PC端最新浏览器已经开始支持了,但还不全面: HTML5是由W3C和WHATWG合作的结果: W3C是万维网联盟,主要 ...

  6. 文档声明Doctype和Doctype html区别 文档类型定义(DTD)

    文档类型定义(DTD)可定义合法的XML文档构建模块.它使用一系列合法的元素来定义文档的结构. DTD 可被成行地声明于 XML 文档中,也可作为一个外部引用. 文档声明的作用: 文档声明是为了告诉浏 ...

  7. 文档类型定义和合法性(2)

    8.5.3 子元素列表 由于SEASON元素被声明为可以接受任何元素作为子元素,因而可以接受各种各样的元素.当遇到那些多多少少有些非结构化的文本,如杂志文章时,这种情况就很有用.这时段落.副栏.项目列 ...

  8. DOCTYPE html PUBLIC 指定了 HTML 文档遵循的文档类型定义

    DOCTYPE html PUBLIC 指定了 HTML 文档遵循的文档类型定义 今天看到一篇CSS应用的一个友好搜索,我按网页上的代码复制.粘贴后预览时总达不到效果,而直接拷贝他的实例却能达到效果, ...

  9. J2EE之dtd(文档类型定义)

    一:良好xml的格式 1:xml的作用 1.1 数据交互(两种方式) 第一种:{name:xxx,sex:'男',age:18},{name:xxx,sex:'男',age:18},{name:xxx ...

最新文章

  1. 我国科学家成功研制全球神经元规模最大的类脑计算机
  2. linux更新模块,Linux下Nginx的安装、升级及动态添加模块
  3. 财贸企业实行国有民营机制的调查
  4. 硬盘损坏如何恢oracle,硬盘物理损坏,如何恢复数据库?
  5. python运行pyc文件_python中__pyc__文件的生成和作用
  6. 随想录(读书和选书)
  7. lua绑定c++的时候常见得错误
  8. Javascript:实现字符串replaceAll方法
  9. React入门第一天(绑定事件,动态渲染,修改样式、传参)
  10. 树莓派保持网络连接shell脚本
  11. Alice and the List of Presents CodeForces - 1236B 数学推导
  12. Open-set Adversarial Defense with Clean-Adversarial Mutual Learning
  13. 如何重新设置苹果id密码_ios游戏apple账号分享韩国苹果id密码大全
  14. Java系列之JDBC和ODBC之间的区别与联系
  15. 生物科学与计算机科学计算案例,北京林业大学计算生物学与生物信息学考研经验-生物科学技术辅导...
  16. python selenium 火狐下载文件
  17. 基于Mtk平台的android camera hal3学习
  18. 2020年Java语言发展现状
  19. docker下自定义分词器词库
  20. 网络与信息安全学习(二)

热门文章

  1. 【HNOI2016】序列【莫队】【单调栈】【ST表】
  2. The 2019 ICPC Asia Shanghai Regional Contest
  3. Intervals on the Ring
  4. E - Another Postman Problem FZU - 2038
  5. 牛客题霸 [ 换钱的最少货币数] C++题解/答案
  6. 【无码专区1】简单路径的第二大边权(启发式合并+最小生成树)
  7. P3320:寻宝游戏(生成树)
  8. P2568-GCD【欧拉函数,欧拉筛】
  9. ssl1463-公共子串【各种dp之1】
  10. 【数论】YY的GCD(P2257)