日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

XML——文档类型定义(DTD-Document Type Definition)

發(fā)布時間:2023/12/3 asp.net 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 XML——文档类型定义(DTD-Document Type Definition) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【0】README

0.1)本文文字描述轉(zhuǎn)自 core java volume 2 , 旨在理解 XML——文檔類型定義(DTD-Document Type Definition) 的基礎(chǔ)知識;
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相關(guān)

1)提供DTD的方式有多種,可以將其納入到 XML文檔中:

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

2)正如你所看到的,這些規(guī)則被納入到了 DOCTYPE聲明中, 該代碼塊使用 […] 來限定其界限;文檔類型必須匹配根元素的名字,比如 荔枝中的configuration;
3)在XML 文檔內(nèi)部使用 DTD 不是很普遍,因為DTD會使文件長度變得很長,把DTD存儲在外面更具有意義; (干貨——在XML 文檔內(nèi)部使用 DTD 不是很普遍,因為DTD會使文件長度變得很長,把DTD存儲在外面,這也是引入SYSTEM聲明的原因)

  • 3.1)SYSTEM聲明可以用來實現(xiàn)這個目標,你可以指定一個包含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)如果必須從一個輸入流來解析,請?zhí)峁┮粋€實體解析器;

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標識符,請調(diào)用 DocumentBuilder 類的 setEntityResolver 方法來安裝 EntityResolver 接口的某個實現(xiàn)類的一個對象。該接口只有一個方法:resolveEntity;
  • A2) 下面是一個典型實現(xiàn)的代碼框架:
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 或字符串構(gòu)建輸入源;

5) 現(xiàn)在你知道了 解析器怎樣定位 DTD了,下面,看看不同類型的規(guī)則:

  • 5.1)ELEMENT 規(guī)則:用于指定某個 元素可以擁有什么樣的子元素;可以指定一個正則表達式,如下表所示: (干貨——ELEMENT 規(guī)則和正則表達式結(jié)合起來)

  • 5.2) 下面是一些簡單而典型的荔枝。 下面的規(guī)則聲明了 menu 元素包含0個或多個item 元素:

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

Attention)

  • A1) PCDATA = parsed char data, 表示已解析的字符數(shù)據(jù); (干貨——PCDATA定義 not CDATA 定義)
  • A2)數(shù)據(jù)是已解析的,因為 解析器通過尋找表示一個新標簽起始的 < 字符或 表示一個實體起始的 & 字符, 而解釋了這些文本字符串;

  • 5.4) 元素的規(guī)格說明可以包含 嵌套的和復(fù)制的正則表達式, 如, 下面是一個描述了本書中每一章的結(jié)構(gòu)的規(guī)則: (干貨——元素的規(guī)格說明可以包含 嵌套的和復(fù)制的正則表達式)

<!ELEMENT chapter (intro,(heading,(para|image|table|noe)+)+)> 每章都以簡潔開頭, 其后是一個或多個小節(jié), 每個小節(jié)有一個標題和一個或多個段落,圖片,表格或說明構(gòu)成;
  • 5.5)有一種常見的case 是: 不能把規(guī)則定義得像你希望的那樣靈活。當一個元素可以包含文本時,那么就只有兩種合法的cases:
    • case1)要么元素只包含文本, 比如 <!ELEMENT name (#PCDATA)> ;
    • case2)要么元素只包含任意順序的文本和標簽的組合, 比如 <!ELEMENT para (#PCDATA|em|strong|code)*> ;
  • 5.6)指定其他包含 #PCDATA 規(guī)則的類型都是不合法的。如,以下規(guī)則是非法的:
<!ELEMENT captionedImage (image, #PCDATA)> , 必須重寫一個規(guī)則,以引入另一個 caption 元素或 允許 使用 image 元素或文本的組合;
  • 5.6.1)這種限制簡化了XML 解析器在解析混合式內(nèi)容(標簽和文本的混合)時的工作。因為在允許混合式內(nèi)容時難免失控, 所以最好在設(shè)計 dtd時, 讓其中所有的元素要么包含 其中元素,要么只包含文本;
  • 5.7) 還可以指定描述合法的元素屬性的規(guī)則, 通用語法為: (干貨——還可以指定描述合法的元素屬性的規(guī)則)
    <!ATTLIST element attribute type default>

  • 5.7.1)下面是兩個典型的屬性規(guī)格說明:

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

    • A1)第一個規(guī)格說明: 描述了font元素的style 屬性, 它有4個合法的屬性值, 默認值是 plain;
    • A2)第二個規(guī)則說明: 表示 size 元素的unit 屬性 可以包含任意字符數(shù)據(jù)序列;
  • 5.8) 表2-2 顯示了合法的屬性類型, 表2-3 顯示了屬性默認值 的語法: (干貨——CDATA定義)

Attention)

  • A1)一般情況下,我們推薦用元素而非屬性來描述數(shù)據(jù);
  • A2)屬性有一個不可否認的優(yōu)點: 那就是解析器能夠校驗取值是否合法,

6)CDATA屬性值的處理與你前面看到的處理 #PCDATA有著微妙的差別: 并且與 < ![CDATA[...]]> 部分沒有多大關(guān)系。 屬性值首先被規(guī)范化, 也就是說, 解析器要處理對字符和實體的引用, 并且要用空格來替換空白字符;

  • 6.1)NMTOKEN(即名字標記)與 CDATA相似: 但是大多數(shù)非字母數(shù)字字符和內(nèi)部的空白字符是不允許使用的, 而且解析器會刪除起始和結(jié)尾的空白字符。NMTOKENS 是一個以空白字符分隔的名字標記列表;
  • 6.2) 屬性類型介紹:
    • 6.2.1)ID: ID 結(jié)構(gòu)是有用的, ID 是在文檔中唯一的名字標記,解析器會檢查其唯一性;
    • 6.2.2)IDREF: IDREF 是對同一個文檔中 已存在的ID的應(yīng)用;解析器也會對它進行檢查;
    • 6.2.3)IDREFS: IDREFS 是以空白字符分割的 ID 引用的列表;
  • 6.3)ENTITY 屬性值: 將引用一個 “未解析的外部實體”, 這是從 SGML將那里沿用下來的, 在實際應(yīng)用中很少見;
  • 6.4)DTD 也可以定義實體,或定義解析過程中被替換的縮寫。 (干貨——DTD 也可以定義實體, 而其他地方的文本可以包含對這個實體的引用)
    • 6.4.1)看個荔枝:
<!ENTITY back.label "Back"> 其他地方的文本可以包含對這個實體的引用,如: <menuitem label = "&back.label; "/>

7)Conclusion: 這樣,我們就結(jié)束了對 DTD 的介紹了。你已經(jīng)知道如何 使用 DTD了;你可以配置你的解析器以充分利用他們; (干貨——如何配置XML解析器)

  • C1)首先,通知文檔生成工程打開驗證特性:
    factory.setValidating(true);
  • C2)這樣, 該工廠生成的所有文檔生成器都將根據(jù)DTD 來驗證他們的輸入。驗證的最大好處是可以忽略元素內(nèi)容的空白字符, 如,考慮如下代碼:
<font><name>a</name><size>a</size> </font>
  • C3)一個不進行驗證的解析器會報告 font, name 和 size 元素之間的空白字符, 因為它無法知道 font 的子元素是: (name, size) (#PCDATA, name, size) * 還是 ANY;
  • C4)一旦 DTD 指定了子元素是 (name, size), 解析器就知道他們之間的空白字符不是文本。調(diào)用下面的代碼:
    factory.setIgnoringElementContentWhitespace(true); (干貨——將dtd綁定到xml后,必須進行設(shè)置setIgnoringElementContentWhitespace)
    這樣, 生成器就不會報告文本節(jié)點中的空白字符, 這意味著, 你可以依賴 font 節(jié)點只有2個子元素的事實。
  • C5)你只需要 通過如下代碼訪問第一個和第二個元素:
Element e1 = (Element) children.item(0); Element e1 = (Element) children.item(1);


  • C6)這就是 DTD 如此有用的原因。 (干貨——這就是 DTD 如此有用的原因)
  • C7) 當解析器報告錯誤的時候, 應(yīng)用程序希望對該錯誤執(zhí)行某些操作; (干貨——當解析器報告錯誤的時候, 應(yīng)用程序希望對該錯誤執(zhí)行某些操作)
    • C7.1)在驗證時, 應(yīng)該安裝一個 錯誤處理器,這需要提供一個實現(xiàn)了 ErrorHandler 接口的對象,這個接口有3個方法:
void warning(SAXParseException exception) void error(SAXParseException exception) void fatalError(SAXParseException exception) 可以通過 DocumentBuilder 類的 setErrorHandler 方法來安裝 錯誤處理器: builder.setErrorHandler(handler);

總結(jié)

以上是生活随笔為你收集整理的XML——文档类型定义(DTD-Document Type Definition)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。