Posted on 2006-03-26 21:44
fortune 閱讀(1294)
評論(1) 編輯 收藏 所屬分類:
java技術
本文是技巧文章系列的第一篇文章,這些技巧文章將作為在 Java 編程語言中使用 XML 的綜合指南。 我從討論 SAX API 開始。本篇技巧文章回顧了如何獲取 SAX 解析器實例以及如何對該解析器設置各種功能和屬性。
在 Java 中使用 XML 是一個內容相當豐富的主題;可以使用多個 API,而且許多 API 使得使用 XML 簡單得如同從文本文檔讀取行。基于樹的 API(如 DOM)展現了一個內存中的 XML 結構,該結構對于 GUI 和編輯器來說是最理想的,基于流的 API(如 SAX)對于只需要獲取文檔數據的高性能應用程序來說很重要。在本技巧文章系列中,我將從基礎知識開始一步步地教您如何在 Java 中使用 XML。同時,您將學習許多甚至連眾多專業人士都不知道的訣竅,所以即使您已經具有一些 XML 經驗,也應該仔細閱讀本教程。
我從 SAX(Simple API for XML)開始。雖然該 API 或許是 Java 和 XML API 中最難以掌握的,但它可能也是功能最強的 API。另外,大多數其它 API 實現(象 DOM 解析器、JDOM 和 dom4j 等)都部分地基于 SAX 解析器。對于用 XML 和 Java 語言所做的每一件事情,理解 SAX 會給予您一個良好的開端。特別在本篇技巧文章中,我將討論如何獲取 SAX 解析器實例以及如何對該解析器設置一些基本功能和屬性。
注:我假設您已經下載了一個符合 SAX 的解析器(如 Apache Xerces-J)(請參閱 參考資料以獲取鏈接)。Apache 站點有大量關于如何進行設置的信息,但是,基本上您只需要將已下載的 JAR 文件放入 CLASSPATH
中。這些示例假設您的解析器可用。
獲取解析器
使用 SAX 的第一步實際上是獲取解析器實例。在 SAX 中,由 org.xml.sax.XMLReader
類的實例表示解析器。我在上一篇技巧文章(“Achieving vendor independence with SAX”— 請參閱 參考資料)中對它進行了詳細討論,所以我將不會在這里花大量的時間在上面。清單 1 顯示了在無需編寫與供應商相關的代碼的情況下獲取新 SAX 解析器實例的正確方法。
清單 1. 獲取 SAX 解析器實例
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
|
通過使用這個方法,您需要將系統屬性 org.xml.sax.driver
設置成想要裝入的解析器的類名。這是特定于供應商的類;對于 Xerces,它應該是 org.apache.xerces.parsers.SAXParser
。用 -D
開關將這個參數指定給 Java 編譯器:
java -Dorg.xml.sax.driver=org.apache.xerces.parsers.SAXParser some.sample.Class
|
當然,您要確保指定的類存在并在類路徑上。
功能
一旦有了解析器實例,就需要配置它。請注意,這與設置解析器來處理 XML 中的錯誤、內容或結構不同;相反,配置是實際告訴解析器如何操作的過程。您可以打開驗證、關閉名稱空間檢查及擴展實體。這些行為完全獨立于特定的 XML 文檔,因此涉及與新解析器實例的交互。
注:對于那些過于急燥的人來說(我知道您不是這樣的),我當然會處理內容、錯誤處理及類似的東西。然而,這些主題將在未來的技巧文章中討論,所以您還得復查。眼下,我們只關注配置、功能和屬性。
可以用兩種方法配置解析器:功能和屬性。 功能包括打開或關閉特定功能,比如驗證。 屬性包括設置解析器所使用的特定項的值,如用來驗證所有文檔的模式位置。我將先討論功能,然后在下一節研究屬性。
功能是通過解析器上名為 setFeature()
的方法設置的,這一點并不奇怪。語法類似于清單 2 所示。
清單 2. 設置 SAX 解析器的功能
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
String featureName = "some feature URI";
boolean featureOn = true;
try {
parser.setFeature(featureName, featureOn);
} catch (SAXNotRecognizedException e) {
System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
System.err.println("Error in setting feature: " + e.getMessage());
}
|
這相當清楚,不需要說明;關鍵是知道可用于 SAX 解析器的常見功能。每個功能均由一個特定的 URI 標識。可以從 SAX 網站在線獲得這些 URI 的完整列表(請參閱 參考資料)。一些最常見的功能是驗證和名稱空間處理。清單 3 顯示了設置這兩種屬性的示例。
清單 3. 一些常見功能
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
try {
// Turn on validation
parser.setFeature("http://xml.org/sax/features/validation", true);
// Ensure namespace processing is on (the default)
parser.setFeature("http://xml.org/sax/features/namespaces", true);
} catch (SAXNotRecognizedException e) {
System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
System.err.println("Error in setting feature: " + e.getMessage());
}
|
請注意,雖然解析器有幾個標準 SAX 功能,但這些解析器可以自由地添加自己的特定于供應商的功能。例如,Apache Xerces-J 添加了一些考慮動態驗證以及遇到致命錯誤之后繼續處理的功能。請參考解析器供應商的文檔,以獲取相關的功能 URI。
屬性
一旦理解了功能,就很容易理解屬性。除了屬性將對象作為參數而功能獲取布爾值外,它們以完全相同的方式操作。我們使用 setProperty()
方法來設置屬性,如清單 4 所示。
清單 4. 設置 SAX 解析器的屬性
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
String propertyName = "some property URI";
try {
parser.setProperty(propertyName, obj-arg);
} catch (SAXNotRecognizedException e) {
System.err.println("Unknown property specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
System.err.println("Unsupported property specified: " + e.getMessage());
} catch (SAXException e) {
System.err.println("Error in setting property: " + e.getMessage());
}
|
這里使用相同的錯誤處理框架,所以您可以容易地在兩種類型的配置選項之間復制代碼。和功能一樣,SAX 提供了一組標準屬性,供應商可以添加他們自己的擴展。常見的 SAX 標準的屬性考慮到了設置詞法處理程序(Lexical Handler)和聲明處理程序(Declaration Handler)(我將在以后的技巧文章中討論這兩個處理程序)。像 Apache Xerces 之類的解析器對它們進行了擴展,例如,使它們能夠設置輸入緩沖區大小以及要在驗證中使用的外部模式的位置。清單 5 顯示了幾個實際使用中的屬性。
清單 5. 一些常見屬性
// Obtain an instance of an XMLReader implementation from a system property
XMLReader parser = org.xml.sax.helpers.XMLReaderFactory.createXMLReader();
try {
// Set the chunk to read in by SAX
parser.setProperty("http://apache.org/xml/properties/input-buffer-size",
new Integer(2048));
// Set a LexicalHandler
parser.setProperty("http://xml.org/sax/properties/lexical-handler",
new MyLexicalHandler());
} catch (SAXNotRecognizedException e) {
System.err.println("Unknown feature specified: " + e.getMessage());
} catch (SAXNotSupportedException e) {
System.err.println("Unsupported feature specified: " + e.getMessage());
} catch (SAXException e) {
System.err.println("Error in setting feature: " + e.getMessage());
}
|