曝光臺 注意防騙
網曝天貓店富美金盛家居專營店坑蒙拐騙欺詐消費者
夠對它重新解碼,而不得不先把它作為字節流進行編碼(如U T F - 8編碼所要求)。最好由解析器
直接處理字節流。(實際上關于是否希望在S A X里提供這種選擇還有一些爭論。但是它顯然很有
用處,它不完全符合X M L規范的精神,X M L規范嚴格定義了X M L文檔為字節序列。也許最好是
不把輸入字符流看作是一個X M L文檔,而是當作一個經過預處理的X M L文檔,該文檔已經完成
了第一步處理,即字節的解碼。)
對于是使用字節流還是字符流,有一個值得注意的障礙:解析器無法解析源文檔中出現的
相對U R L。假設源文檔包含下面這樣一行:
166使用XML 高級編程
下載
到哪里去找b o o k s . d t d? X M L規范說明(事實上)應該在和源文檔相同的目錄下,但是當然
并沒有源文檔目錄,因為當開始解析時它是在內存中。
S A X通過允許用字節流或字符流提交系統標識(即U R L)避免了這種情況。這個U R L不是
用于讀取源文檔,而只是作為一個用以解析源文檔中出現的相對U R L的基礎。
2. 指定文件名而不是U R L
另一個常見的輸入源是文件名:例如,命令行接口一般使用文件名而不是U R L作為輸入參
數,而且你可能想在應用程序接口中也使用這種形式的參數。
SAX InputSource類不直接支持為輸入指定一個文件名;你必須把文件名轉換成U R L以使解
析器能夠處理它。如果使用Java 2 就簡單了: Java File 類有一個相配的方法。要解析文件
c : \ s a m p l e . x m l,你可以寫這樣的語句:
(注意parse( )方法要求U R L是一個字符串而不是一個Java URL對象,因此需要調用toString( )實
現這種轉換。)
對于Java 1.1,如果想讓代碼能夠同時在Wi n d o w s和U N I X上運行,那么把文件名轉換成U R L
就要比想象中的稍微困難一點,因為有很多種文件名格式。下面的方法能夠處理絕大多數格式,
盡管錯誤處理還不完善:
程序清單6 - 1 5
3. 非X M L輸入源
S A X使用的更令人驚奇的一種輸入方式是把根本不是X M L形式的數據提交給應用程序。只
要數據是分層格式并可以被合理地映射到X M L數據模型,你就可以編寫一個各種操作類似X M L
解析器的驅動程序。驅動程序發送如startElement( ) 和endElement( ) 的事件給應用程序的
D o c u m e n t H a n d l e r,就像數據是來源于一個X M L文檔,實際上并不存在一個要解析的X M L文檔。
為什么要這樣做?它可以利用為接收X M L數據而編寫的應用程序,而不經過先以X M L格式
編寫數據然后再進行解析這種笨拙的處理過程。例如,如果有一個應用程序,程序是為處理電
第6章SAX 1.0: XML簡易API使用167 下載
子商務的輸入X M L - E D I消息而設計的,你也許就想編寫一個轉換程序,能夠把比較老的專有格
式的消息提交給應用程序處理。轉換程序的一種實現方法是創建一個X M L文件然后把文件提交
給應用程序。但是如果目標應用程序是為使用S A X編寫的,有一個巧妙的簡便方法,就是轉換
程序假裝是一個X M L解析器去直接調用應用程序。
下面關于S A X過濾器的章節將討論使用這種方法的可能性。
6.3.2 處理外部實體
人們經常把在文檔文本中出現的像& a u m l a u t ;形式的標志看作X M L實體。這并不完全準
確:& a u m l a u t ;嚴格來說不是一個實體,而是一個實體參照。實體是& a u m l a u t ;所應用的對象,這
就是D T D中的定義,此定義把“ a u m l a u t”和它的擴展文本“ ä”聯系起來。
在X M L中有許多不同種類的實體,要非常謹慎地明確我們討論的是哪種實體。如第3章中所
提到的,包括表6 - 3所列各項。
表6 - 3
實體描述
字符引用( Character references) 以數值編碼(十進制或十六進制)指定的字符,如& # x a ;
或& # 1 0 ;(這些并不是嚴格意義上的實體,為了完備性,在
此處包含這種情況)
預定義實體( Predefined entities) X M L標準中定義的特殊的實體參照,如& l t ;和& a m p ;只是
唯一一種不需要在D T D中有相應定義(內部或外部)而使用
的實體參照
內部實體( Internal entities) 其擴展文本在D T D中定義(不作為對一些外部存儲對象的
引用)
外部解析實體(External parsed entities) 其擴展文本是在一個獨立文件中定義的完備的X M L形式,
該文件是從主X M L文檔通過系統標識或U R L引用的
非解析實體( Unparsed entities) 包括非X M L數據(例如二進制編碼圖像):總是外部的。
真正的格式可以是以符號形式標識
參數實體( Parameter entities) 包括D T D而不是文檔主體的組成部分
文檔實體( Document entity) 主源X M L文檔本身就是一個實體
外部文件類型定義( External DTD) 如果文檔應用了一個外部D T D,那么D T D也是一個實體
S A X中處理實體的功能關注于解析對外部實體的引用,外部實體即存放于不同“文件”中
的數據—更嚴格地說,是存放于被系統標識或公共標識識別的容器中。內部實體、字符引用
和預定義實體被解析器直接處理,應用程序不能干預它們擴展的方式。
X M L中的外部實體總是由一個系統標識來識別(一個U R L或更實際的類似于U R L的東西),
或者也可以是由一個公共標識來識別。公共標識為S G M L預先考慮:盡管基于已經建立的S G M L
慣例有一些約定,XML 標準(S A X同樣如此)并不真正說明公共標識用來做什么和應該如何使
用。
很多情況下,通過解釋系統標識或U R L來解析外部實體引用的標準規則實際上是不夠的。
這些情況包括:
• 當實體存放在數據庫中(或任何其他不能直接被U R L尋址的地方,例如字處理系統中的短
168使用XML 高級編程
下載
語庫)。
• 當同一個實體引用根據上下文被分別解析。例如, & c u r r e n t U s e r ;實體引用可能被擴展為當
前登錄用戶的名字。
中國航空網 www.k6050.com
航空翻譯 www.aviation.cn
本文鏈接地址:
XML高級編程上(63)