SAX(Simple API for XML)は、もう一つの標準XML操作用APIです。DOMと違い、イベント駆動型のAPIなので使いこなすには多少慣れが必要ですが、DOMより数倍高速に動作し、メモリの使用量も少ないので、スピードの要求される処理や、巨大なファイルの処理に向いています。詳しくは、XML関係の書籍か、Webサイトを参照してください。
リスト[ReadBySAX.java]は、今回のサンプルデータリスト[XMLデータ]を読み込むプログラムです。主な流れは、
のようになっています。
import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; import java.io.File; import java.io.IOException; import java.util.Stack; import java.util.List; import java.util.ArrayList; public class ReadBySAX { public static void main(String [] args) { //データを読んで DataItem [] items = getDataItems("data.xml"); //表示 for (int i=0;i<items.length;i++) { System.out.println("Name["+items[i].getName()+"]"); System.out.println("Cost["+items[i].getCost()+"]"); System.out.println("Note["+items[i].getNote()+"]"); System.out.println("--------"); } } // filename から DataItem 配列 static DataItem [] getDataItems(String filename) { DataItemHandler handler = new DataItemHandler(); try { getSAXParser().parse(new File(filename),handler); } catch (Exception e) { e.printStackTrace(); System.exit(1); } return handler.getDataItems(); } // JAXP API static SAXParser getSAXParser() { SAXParserFactory spf = SAXParserFactory.newInstance(); try { return spf.newSAXParser(); } catch (Exception e) { e.printStackTrace(); System.exit(1); } return null; } // SAX 用 イベントハンドラ static private class DataItemHandler extends DefaultHandler { List items = new ArrayList(); DataItem currentItem; Stack tagStack = new Stack(); DataItem [] getDataItems() { DataItem [] ret = new DataItem[items.size()]; return (DataItem[])items.toArray(ret); } String getCurrentTag() { return (String)tagStack.peek(); } // タグの開始位置に来ると呼ばれる public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { if (qName.equals("dataItem")) { currentItem = new DataItem(); } tagStack.push(qName); // 現在のタグ名を保存 } // 内容を読み取ったときに呼ばれる public void characters(char[] ch,int start,int length) throws SAXException { String text = new String(ch,start,length).trim(); if (text.length()==0) return;//省略可能なスペース if (getCurrentTag().equals("name")) { currentItem.setName(text); } else if (getCurrentTag().equals("cost")) { currentItem.setCost(Integer.parseInt(text)); } else if (getCurrentTag().equals("note")) { currentItem.setNote(text); } } // 終了タグに来たら呼ばれる public void endElement(String namespaceURI, String localName, String qName) throws SAXException { if (getCurrentTag().equals("dataItem")) { items.add(currentItem); } tagStack.pop(); } } }
java ReadBySAX Name[コーヒー] Cost[120] Note[主食] -------- Name[チョコレート] Cost[180] Note[オヤツ] -------- Name[ノート] Cost[150] Note[いつでもどこでもアイデアを記録] --------