Download presentation
Presentation is loading. Please wait.
1
第6回 2007年6月1日 応用Java (Java/XML)
2
前回までやったこと 「XMLパーサ」-- Java でXMLを処理 javax.xml.stream パッケージのパーサ
イベントの種類の調べる 応用(1) – テーブルの利用 「要素の出現回数を調べる」 応用(2) – フィルタ的な処理 java.util.Map, java.util.Set 応用(3) – MS Office 2007 のファイルを処理する
3
本日(6/1)の講義内容 javax.xml.stream の処理の再設計 処理内容を複数のクラスに分ける
SAX(Simple API for XML)の処理
4
(復習) パッケージとAPI javax.xml.stream XMLEventReader インタフェース
XMLInputFactory クラス javax.xml.stream.events XMLEvent インタフェース サブインタフェース群 StartDocument, EndDocument, StartElement, EndElement, Characters
5
その他のパーサの利用 javax.xml.parsers パッケージ SAXパーサ、DOMパーサを提供 org.xml.sax パッケージ
org.w3c.dom パッケージ
6
プログラムの基本部分(1) import javax.xml.stream.events.*;
XMLEventReaderTest1.java import javax.xml.stream.*; import javax.xml.stream.events.*; import javax.xml.transform.stream.*; public class XMLEventReaderTest1 { public static void main( String[] args ) {
7
プログラムの基本部分(2) try { StreamSource source = new StreamSource( args[0] ); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( source );
8
プログラムの基本部分(3) int count=0; while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); if( event.isStartElement() ) { ((StartElement).event).getName(); : }
9
イベントの場合分けの工夫 処理をメソッドに分割する XMLEvent event = reader.nextEvent();
if( event.isStartElement() ) { startElement( (StartElement)event ); } else if( event.isEndElement() ) { endElement( (EndElement)event ); } :
10
クラスへの分割を考えてみる 文書の入力先とパーサの取得 イベントの場合分けと処理の呼び出し 各イベントごとの処理の内容
11
設計案1)単純に3クラスに ParserTest – 文書の指定とパーサの取得
EventCase – イベントの場合分けとメソッドの呼び出し EventProc – イベントの処理の内容の記述
12
文書の指定とパーサ取得 public class ParserTest { public static void main( String[] ) { try { Source s = new StreamSource( name ); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( s ); EventCase ec = new EventCase(); ec.dispatch( reader );
13
場合分けのクラス public class EventCase { public void dispatch( XMLEventReader r ); try{ EventProc proc = new EventProc(); while( r.hasNext() ) { XMLEvent event = r.nextEvent(); if( event.isStartElement() ) { proc.startElement(); } :
14
処理の内容のクラス public class EventProc { public void startElement( StartElement se) { : } public void endElement( EndElement ee ) { public void characters ( Characters ch ) {
15
もうひと工夫 イベントの場合分けはいつも同じ 表に出なくてもいいのでは? 1つの方法:「クラスの継承」
AbstractEventProcessor クラス イベントの場合分けと呼び出しを記述 EventProcessorクラス 処理の内容の記述 public class EventProcessor extends AbstractEventProcessor {
16
さらに厳密にする インタフェースの導入 メソッドの名前、型を常に同じに制約
public interface EventProcessorIF { public void startElement( StartElement es); public void endElement( EndElement ee ); public void characters( Characters ch ); : }
17
継承関係 public abstract class AbstractEventProcessor
implements EventProcessorIF { public void process ( XMLEventReader r ) { while( r.hasNext() ) { XMLEvent event = r.nextEvent(); if( event.isStartElement( ) ) { startElement( (StartElement)event) ; } : public abstract void startElement(StartEement se );
18
SAXによる処理 javax.xml.parsers 最も初期から利用可能だったパーサ 目的、設計は「今回の工夫」と共通
19
javax.xml.parsers 最も抽象化されたレベル(JAXP) パーサを「取り出す」ための仕組みを提供 SAXParser,
SAXParserFactory DocumentBuilder, DocumentBuilderFactory 唯一の手段ではないが、「標準」を提供 パーサの実装に制限は課さない
20
パーサを取得するパターン(1) SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser parser = spf.newSAXParser(); XMLReader reader = parser.getXMLReader();
21
再度 Factory の「パターン」! XMLInputFactory factory =
XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( source ); Factoryクラスはまず自分のインスタンスを作る Factoryのインスタンスから実際に処理を行うインスタンスを得る
22
SAXの処理の特徴 XML文書を読み込みながら処理 特定の「節目」でイベントが発生 (イベント駆動型の処理)
イベントの処理はHandlerが担当 ContentHandler(のサブクラス) ErrorHandler(のサブクラス)
23
XMLReaderへのHandlerの登録
XMLReader reader = parser.getXMLReader(); reader.setContentHandler( new MyContentHandler() ); reader.setErrorHandler( new MyErrorHandler() );
24
その後で、パーシングを開始 XMLReader reader …. : InputSource source =
new InputSource( “sample.xml” ); reader.parse( source );
25
SAXの処理の特徴 XML文書の読み込みと処理が並行に進行 要素(タグ)ごとに逐次処理 読み込みと処理は同時に終了
(後処理には別の機構が必要)
26
ContentHandler の主要な仕事
startDocument() – パーシングの開始時 endDocument() – パーシングの終了時 startElement() – 要素(タグ)の開始 endElement() – 要素(タグ)の終了 characters() – 平文テキストの読み込み
27
ContentHandler その他の機能
名前空間の処理 妥当性の検証とWhite Spaceの処理 *以上は次回以降に利用
28
ErrorHandlerの仕事 3つのエラーレベル fatalError 文書名の間違い、不存在 XML文書として不適切(文法エラー)
warning エラーではない不適切な記述
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.