XMLタグのカスタマイズ機能は非常に強力です。例えば、この記事で説明するDTD(Document型定義)は、人々にオブジェクト指向のような感覚を与えます。 XML を見てみる DTD ファイル タイプ定義の完全な分析
1. DTD とは
DTD の正式名は Document Type Definition です。これは、XML ファイル構造を指定し、XML ファイル タイプ定義の構文と規則を提供するファイル定義形式です。 XML ファイル。 DTDでXMLファイルの構造を定義し、DTDの宣言に従ってXMLファイルを記述します。 プログラミング言語の関数定義と同じように、関数を使用するときは、関数宣言の形式に従って引用符で囲む必要があります。
2. DTDの詳細説明
1. 例の詳細説明
<?xml version='1.0' encoding='utf-8'?> <!-- 声明内部DTD --> <!DOCTYPE 影片目录[ <!ELEMENT 影片目录 (影片)+> <!-- 声明XML顶层元素的子元素“影片”,“+”表示有一个或多个影片子元素 --> <!ELEMENT 影片 (片名,主演,导演,简介)> <!-- 声明“影片”元素的子元素 --> <!ATTLIST 影片 类别 CDATA "动作" 年份 CDATA #REQUIRED> <!-- 声明“影片”元素的属性,两属性分别为“类别”和“年份”,CDATA说明属性的类型为字符型 --> <!ENTITY 十面埋伏 "漫天大雪,三人在雪中决斗"> <!-- 实体的声明,类型为字符型,在下面使用“&实体名称;”直接引用 --> <!ENTITY 霍元甲 "民族英雄,与西方帝国主义抗争"> <!ELEMENT 片名 (#PCDATA)> <!ELEMENT 主演 (#PCDATA)> <!ELEMENT 导演 (#PCDATA)> <!ELEMENT 简介 (#PCDATA)> ]> <!-- 由DTD获得的XML --> <影片目录> <影片 类别="武侠" 年份="2008"> <片名>十面埋伏</片名> <主演>刘德华、金城武、章子怡</主演> <导演>张艺谋</导演> <简介>&十面埋伏;</简介> </影片> <影片 类别="武侠" 年份="2006"> <片名>霍元甲</片名> <主演>李连杰</主演> <导演>于仁泰</导演> <简介>&霍元甲;</简介> </影片> </影片目录>
1.1 DTD宣言開始文
(1) 内部宣言:320cc1293465ccf68a56a86baba19d96
( 2) 外部宣言: 7efb260401a327b8213cef1c7ab53bda
外部宣言には多くの形式があり、主に SYSTEM と PUBLIC に分けられますタイプ ファイル 。
システム: 作成者または組織によって作成された多くの XML ドキュメントの中で共通の DTD。
パブリック: 権威ある組織によって開発され、特定の業界または公共の使用のために提供された DTD。
1.2 その他宣言
(1) 要素:
<!ELEMENT element_name element_definition>
(2) 属性リスト:
<!ATTLIST Element_Name Attribute_Name Type [added_declare] Attribute_Name Type [added_declare] ...... >
(3) エンティティ
内部
全般: 534814d417f2ecbde76607f0b029c013
パラメータ: 3cf814a33ef4a8e6dde0a2020ccc4b7a
パラメータ: c6063070a67149636f8451e903758049
2. 詳細な内容
2.1 要素宣言
要素宣言 これらは、いくつかの特殊な要素宣言と、サブ要素の出現数、選択性、混合型であり、その機能はプログラミング言語の算術演算子や論理演算子に似ています。以下は、複数の要素を含む DTD の例です。
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE 影片目录 [ <!ELEMENT 影片目录 (影片,其它,说明)+> <!-- 使用“+”号表明影片目录中的子元素出现至少一次 --> <!ELEMENT 其它 EMPTY> <!-- 使用EMPTY关键字声明空元素 --> <!ELEMENT 说明 ANY> <!-- 使用ANY关键字声明任何内容的元素 --> <!ELEMENT 影片(片名,主演,导演,简介)> <!-- 含有子元素的元素声明格式 --> <!ATTLIST 影片 名称 ID #FIXED "十面埋伏" 类别 CDATA "动作" 年份 CDATA #REQUIRED 票房 CDATA #IMPLIED > <!-- 属性声明 --> <!ENTITY introduction "漫天大雪,三人在雪中决斗"> <!ELEMENT 片名(#PCDATA)> <!ELEMENT 主演(#PCDATA)> <!ELEMENT 导演(#PCDATA)> <!ELEMENT 简介(#PCDATA)> ]>
要素宣言の基本構文をより深く理解するには、このマップをダウンロードしてください。
2.2 名前の競合
複雑な XML 文書内に同じ名前の要素が現れることがあります。この現象を回避するために、名前空間 と接頭辞識別子が導入されます。
2.2.1 名前空間
xmlns を使用して名前空間を導入し、どの部分がその空間に属しているかをユーザーに伝えます。その機能は他のプログラミング言語の名前空間に似ており、要素の一意性が保証され、競合が回避されます。
<?xml version="1.0" encoding='utf-8'?> <影片 xmlns:h='http://www.abc.edu' xmlns:c='http://www.123.edu'><!-- 使用xmlns:来引用命名空间 --> <db> <h:table>werer</h:table> <!-- 告诉用户,此table是在http://www.abc.edu中定义的 --> <c:table>fdfdsfsdf</c:table> <!-- 告诉用户,此table是在http://www.123.edu中定义的 --> </db> </影片>
役割: 要素と属性を標準化し、それらに一意の識別子を与えます。要素名に矛盾がないことを確認し、その起源を明確にします。
2.2.2 プレフィックス識別子
現在の要素または属性がどの DTD からのものであるかを一意に区別するために、要素名と属性名の前に識別子を追加します。これは、fae077d51b591786197c1ce2523c9adb などの名前空間と組み合わせて使用されることがよくあります。 f2579460b9705f22ccfe2f413b686929。
3. エンティティの詳細な説明
要素があるのになぜエンティティを導入する必要があるのでしょうか? 2 つを区別するには、まずエンティティ導入の目的を確認する必要があります。エンティティ メカニズムは、さまざまな種類のデータを XML ドキュメントに組み込むための時間を大幅に節約するツールです。これは、オブジェクト指向の抽象クラスに似ており、頻繁に使用されるオブジェクトをエンティティに抽象化します。エンティティは、どこで使用されても直接参照できるため、重複が回避されます。
詳しく
(1) 入力できない文字を置き換えるには、キーボードには 26 文字といくつかの簡単な句読点しかなく、文字セットにはキーボードで入力できないさまざまな記号が多数あります。
(2) 以下のような XML 仕様の予約語と競合する一部のコンテンツを置き換えます。
(3) 繰り返されるテキストの大きな段落を置き換えます。
エンティティ参照は、参照の場所に応じて内部参照と外部参照、参照の内容に応じて一般参照とパラメータ参照の 2 種類に分類されます。外部エンティティ参照の例を見てみましょう:
リスト 1: "2.dtd" の宣言
<!-- 声明外部DTD,并保存为2.dtd --> <!ELEMENT 影片目录 (影片)+> <!ELEMENT 影片 (片名,主演,导演,简介)> <!ATTLIST 影片 类别 CDATA "动作" 年份 CDATA #REQUIRED> <!ENTITY 十面埋伏 "漫天大雪,三人在雪中决斗"> <!ENTITY 霍元甲 "民族英雄,与西方帝国主义抗争"> <!ELEMENT 片名 (#PCDATA)> <!ELEMENT 主演 (#PCDATA)> <!ELEMENT 导演 (#PCDATA)> <!ELEMENT 简介 (#PCDATA)> <!ENTITY filmcomment SYSTEM "影评.xml"> <!-- 引用外部通用实体,文件名称为“影评.xml” -->
リスト 2: movie review.xml の内容
<?xml version="1.0" encoding='utf-8'?> <影评> 这些影评都是由XXX公司出品,值得观看! </影评>
リスト 3: xml ファイルの内容。
<?xml version="1.0" encoding='utf-8'?> <影评> 这些影评都是由XXX公司出品,值得观看! </影评>
リスト 3: dtd を使用した XML ファイルのコンテンツ。
<?xml version="1.0" encoding='utf-8'?> <!DOCTYPE 影片目录 SYSTEM "./2.dtd" > <影片目录> <影片 类别="武侠" 年份="2008"> <片名>十面埋伏</片名> <主演>刘德华、金城武、章子怡</主演> <导演>张艺谋</导演> <简介>&十面埋伏;</简介> </影片> <影片 类别="武侠" 年份="2006"> <片名>霍元甲</片名> <主演>李连杰</主演> <导演>于仁泰</导演> <简介>&霍元甲;</简介> </影片> &filmcomment; </影片目录>
リスト 4: IE8 を使用してリスト 3 を開いた後の内容
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE 影片目录 (View Source for full doctype...)> - <影片目录> - <影片 类别="武侠" 年份="2008"> <片名>十面埋伏</片名> <主演>刘德华、金城武、章子怡</主演> <导演>张艺谋</导演> <简介>漫天大雪,三人在雪中决斗</简介> </影片> - <影片 类别="武侠" 年份="2006"> <片名>霍元甲</片名> <主演>李连杰</主演> <导演>于仁泰</导演> <简介>民族英雄,与西方帝国主义抗争</简介> </影片> <影评>这些影评都是由XXX公司出品,值得观看!</影评> </影片目录>
内部和外部很容易理解,主要看一般和参数两种引用的区别。
1.参数实体
清单1:test.dtd,在此该内容单独存在了一个dtd文件中是因为在内部DTD子集中。
参数实体引用不能在标记声明内部出现,可以在标记声明允许出现的地方出现。然而,对于外部DTD子集,则没有这个限制。
<!-- 声明外部DTD,并保存为test.dtd --> <!-- 个人信息实体声明的是参数类型的,可以再各个元素中共同使用该参数 --> <!ENTITY % 个人信息 "(姓名,性别,出生日期)"> <!ELEMENT 学生信息 %个人信息;> <!ELEMENT 教师信息 %个人信息;> <!ELEMENT 员工信息 %个人信息;>
清单2:学校信息.xml文件,引用了外部的test.dtd文件
<?xml version='1.0' encoding='utf-8'?> <!-- 学校信息.xml文件 --> <!-- 引用外部DTD --> <!DOCTYPE 学校信息 SYSTEM './test.dtd'> <!-- 由DTD获得的XML --> <学校信息> <学生信息> <姓名>张三</姓名> <性别>男</性别> <出生日期>2013-10-12</出生日期> </学生信息> <教师信息> <姓名>张三</姓名> <性别>男</性别> <出生日期>2013-10-12</出生日期> </教师信息> <员工信息> <姓名>张三</姓名> <性别>男</性别> <出生日期>2013-10-12</出生日期> </员工信息> </学校信息>
清单3:使用IE8打开清单2的内容后
<?xml version="1.0" encoding="utf-8" ?> - <!-- 声明内部DTD --> <!DOCTYPE 学校信息 (View Source for full doctype...)> - <!-- 由DTD获得的XML --> - <学校信息> - <学生信息> <姓名>张三</姓名> <性别>男</性别> <出生日期>2013-10-12</出生日期> </学生信息> - <教师信息> <姓名>张三</姓名> <性别>男</性别> <出生日期>2013-10-12</出生日期> </教师信息> - <员工信息> <姓名>张三</姓名> <性别>男</性别> <出生日期>2013-10-12</出生日期> </员工信息> </学校信息>
2. 一般实体
可在XML元素中加以引用,也可以在DTD中引用,但参数实体只能在DTD中引用,并且通常情况下只能在外部DTD文档中引用。
3. 对比升华
参数实体与一般实体的区别如下:
(l)在定义参数实体时,实体名前必须加一个“%”号。
(2)参数实体引用以“%”开始,而不是一般实体引用的“&”。
(3)参数实体的内容不仅可以包含文本,还可以包含标记。
(4)参数实体只能应用于DTD,而不能在文档本体中引用。即参数实体只能用来构成DTD的内容,而不能构成文档内容。
(5)参数实体只能在外部DTD文档中使用,无法应用于内部DTD。
外部参数实体与外部一般实体的区别如下:
(1)外部参数实体应用于独立的DTD文档,外部一般实体应用于XML文档。
(2)外部参数实体应用于将多个独立的DTD文档组合为一个大的DTD文档,外部一般实体用于将多个独立的XML文档组合成一个大的XML文档。
四、验证XML文件的合法性
DTD定义了XML文件的使用格式,它从结构和形式上限制了XML文档,通过引用DTD可以形成统一的规范化的XML文档,另外通过使用实体简化了DTD和XML文档的内容。使用DTD验证的XML文档才能称为规范化文档,那如何验证所写的XML文档是否符合DTD的规范呢。通过如下的代码串:
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.xml.sax.InputSource; public class ValidateDTD { public static void main(String[] args){ //在验证前需要把需要验证的XML和规范DTD包含在jar中 try{ DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); //创建一个文档构造工厂 dbf.setValidating(true); DocumentBuilder builder=dbf.newDocumentBuilder(); builder.parse(new InputSource("xml-2-2.xml")); //需要验证的XML名称 }catch(Exception e){ e.printStackTrace(); } } }
上面代码中的类和结构主要完成了XML文档的解析,并且在解析之前验证当前XML文件是否符合某个DTD的定义。在上面的代码运行前需要将需要验证的XML和提供规范化的DTD文档引入到当前ValidateDTD项目中,后运行上面的代码实例,该项目会在项目文件中自动查找规范的DTD,然后验证xml文件。
五、结语
至此,有关文件定义格式的内容已经基本上讨论了一遍,从最初的元素声明到复杂多变的实体类型,DTD的引入无疑为XML的使用指定了一个统一的标准,这种标准是由提供方规定好,使用方遵守的一种规则,并在最后讨论了如何验证引用DTD的XML合法与否。另外描述XML文档结构的不仅仅只有DTD,DTD是一种早期的定义格式,它有很多缺点,如不支持数据类型,不易于扩展等,为了避免这种缺点后来又引入了Schema,它是DTD的继任者,下篇博客将着重讨论Schema。
以上がXML で完全に解析された DTD ドキュメント タイプ定義のサンプル コード (図)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。