[轉]技巧: 有效使用 SAX InputSource

來源:互聯網
上載者:User

 

轉自:http://www.ibm.com/developerworks/cn/xml/tips/x-tipsaxis/index.html

 

當您使用 SAX API 時,所有輸入都從使用 org.xml.sax.InputSource 類開始。這個類包含在 SAX API 中,並且提供了輸入規範(通過類似於檔案或 I/O 流的標準 Java 構造),同時還提供一個公用的系統標識。 接著,SAX 在解析時從 InputSource 抽取這些資訊,從而能夠解析外部實體以及其它特定於文檔來源的資源。

類似地,當您對 SAX 使用封裝器(類似於 JAXP API)時,可以調用不同方法。最後,解析使用 SAX InputSource 。例如,考慮 清單 1 中所示的程式碼片段,它使用 JAXP 來啟動 SAX 解析。


清單 1. 將 JAXP 用於 SAX 解析

SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser parser = spf.newSAXParser(); parser.parse(myFile, myHandler);

 

即使輸入了 java.io.File 檔案,它也會在被轉交給底層 SAX 實現之前轉換成 SAX InputSource 。之所以發生這個轉換,是因為這個 JAXP 代碼最終訪問 org.xml.sax.XMLReader 類,該類只為啟動解析提供 清單 2 中所示的兩個特徵符。


清單 2. 用於 XMLReader 的解析進入點

public void parse(InputSource inputSource); public void parse(String systemID);

 

 

在此基礎上,大多數 SAX 解析器實現(如 Apache Xerces)實際上將字串系統標識轉換為 InputSource ,並將它分配給接收 InputSource 的 parse() 版本。無論您如何編碼自己的應用程式,SAX 最終都接收 InputSource 來用於解析。但是,並非所有這樣處理的方法都同等地好。

為了避免您代碼中出現令人不快的意外,最好直接使用 SAX InputSource 類,而不是讓 JAXP 或 SAX 為您處理這個任務。因為實現必須要處理每種可能的情況,所以您常常會看到構造 InputSource 執行個體的代碼,類似於 清單 3 中所示。


清單 3. 一般的 InputSource 構造方法

InputSource inputSource = new InputSource(); // May be a null parameter inputSource.setByteStream(inputStream); // May be a null parameter inputSource.setCharacterStream(reader); // May be a null parameter inputSource.setSystemId(systemId); // May be a null parameter inputSource.setPublicId(publicId); // Derived parameter inputSource.setEncoding(encoding);

 

 

正如您從注釋中看到的,這些方法中的許多被傳遞了 null 參數。雖然執行這些方法不會花費很多時間,但 XML 解析應用程式中的每一秒都很關鍵;遺憾的是,這些不執行任何操作的方法浪費了寶貴的時間。通過自行構造 InputSource 執行個體,您可以將這個過程簡化為一至兩個方法調用,如 清單 4 所示。


清單 4. 改進 InputSource 構造

InputSource inputSource = new InputSource(myInputStream); inputSource.setSystemId("http://www.oreilly.com"); inputSource.setEncoding("UTF-8");

 

我還使用了 setEncoding() 方法來通知 SAX 解析器使用何種編碼;在涉及國際化或使用多位元組字元集的 XML 應用程式中,這一點很重要。

但是,這裡產生了另一個問題:對於字元編碼,用手工設定字元編碼的編碼與所提供的輸入資料流(通過 java.io.InputStream 或 java.io.Reader )所用的編碼 不同 ,這種情況很常見。如果這些編碼不匹配,就可能發生各種解析問題。要避免這種情況,請始終用 Java InputStream 建立您的 InputSource ,而不要用 Reader 或 String 系統標識(這些都是 JAXP API 的可能選項)。當您提供 InputStream 時,SAX 實現將流封裝在 InputStreamReader 中;然後 SAX 自動從流中檢測正確的字元編碼。隨後,您可以省略 setEncoding() 步驟,再次減少方法調用。結果是應用程式運行更快了,並且字元編碼始終正確。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.