您覺得自己懂 Java 程式設計?事實是,大多數開發人員都隻領會到了 Java 平台的皮毛,所學也隻夠應付工作。有些Java工具無法分類,隻能算作 “有用的東西”。這是developerworks5件事系列中介紹一些您樂于擁有的工具,即使您将它們放到廚房抽屜裡。
編者按:本文為 Neward & Associates 的主管Ted Neward 撰寫的5件你不知道的事情系列的最後一篇(至少目前是這樣)。Ted Neward 在Neward & Associates負責有關 Java、.NET、XML 服務和其他平台的咨詢、指導、教育訓練和推介。他現在居住在華盛頓州西雅圖附近。以下為本文的譯文:
1. StAX
在千禧年左右,當 XML 第一次出現在很多 Java 開發人員面前時,有兩種基本的解析 XML 檔案的方法。SAX 解析器實際是由程式員對事件調用一系列回調方法的大型狀态機。DOM 解析器将整個 XML 文檔加入記憶體,并切割成離散的對象,它們連接配接在一起形成一個樹。該樹描述了文檔的整個 XML Infoset 表示法。這兩個解析器都有缺點:SAX 太低級,無法使用,DOM 代價太大,尤其對于大的 XML 檔案 — 整個樹成了一個龐然大物。幸運的是,Java 開發人員找到第三種方法來解析 XML 檔案,通過對文檔模組化成 “節點”,它們可以從文檔流中一次取出一個,檢查,然後處理或丢棄。這些 “節點” 的 “流” 提供了 SAX 和 DOM 的中間地帶,名為 “Streaming API for XML”,或者叫做StAX。(此縮寫用于區分新的 API 與原來的 SAX 解析器,它與此同名。)StAX 解析器後來包裝到了 JDK 中,在 javax.xml.stream 包。
使用 StAX 相當簡單:執行個體化 XMLEventReader,将它指向一個格式良好的 XML 檔案,然後一次 “拉出” 一個節點(通常用 while 循環),檢視。例如,在清單 1 中,列舉出了 Ant 構造腳本中的所有目标:
清單 1. 隻是讓 StAX 指向目标
import java.io.*;
import javax.xml.namespace.QName;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.stream.util.*;
public class Targets {
public static void main(String[] args) throws Exception
{
for (String arg : args) {
XMLEventReader xsr =XMLInputFactory.newInstance().createXMLEventReader(new FileReader(arg));
while (xsr.hasNext())
{
XMLEvent evt = xsr.nextEvent();
switch (evt.getEventType())
{
case XMLEvent.START_ELEMENT:
{
StartElement se = evt.asStartElement();
if (se.getName().getLocalPart().equals("target"))
{
Attribute targetName = se.getAttributeByName(new QName("name")); // Found a target!
System.out.println(targetName.getValue());
}
break;
} // Ignore everything else
}
}
}
}
}
StAX 解析器不會替換所有的 SAX 和 DOM 代碼。但肯定會讓某些任務容易些。尤其對完成不需要知道 XML 文檔整個樹結構的任務相當友善。
請注意,如果事件對象級别太高,無法使用,StAX 也有一個低級 API 在 XMLStreamReader 中。盡管也許沒有閱讀器有用,StAX 還有一個 XMLEventWriter,同樣,還有一個 XMLStreamWriter 類用于 XML 輸出。