Download presentation
Presentation is loading. Please wait.
1
第4回 2007年5月11日 応用Java (Java/XML)
2
前回までやったこと 「XMLパーサ」-- Java でXMLを処理 javax.xml.stream パッケージのパーサ
XMLEventReader と XMLInputFactory (「Factory のデザインパターン」) XMLEventReader と java.util.Iterator javax.xml.stream.events の XMLEvent イベントの種類の調べる 空白文字のチェック 属性の処理
3
本日(5/11)の講義内容 javax.xml.stream による処理の応用 文書の情報を何度も利用するには? 変数やテーブルの活用
java.util.Collection のフレームワーク Set, HashSet Iterator Map, HashMap
4
(復習1) XMLパーサとは? XML文書内の字句を解析 要素、属性などの情報を取り出す
(アプリケーションが1文字ずつの処理を行う必要はない) <doc> <title> Java and XML </title> <image source=“jax.png” /> </doc>
5
(復習2) XMLパーサの種類 標準のクラスライブラリで提供 (新しくパーサを設計する必要なし) 複数の種類(標準的な処理パターン)
SAX(Simple API for XML) DOM(Document Object Model) javax.xml.streamパッケージ
6
(復習3) パッケージとAPI javax.xml.stream XMLEventReader インタフェース
XMLInputFactory クラス javax.xml.stream.events XMLEvent インタフェース サブインタフェース群 StartDocument, EndDocument, StartElement, EndElement, Characters
7
javax.xml.stream のAPI(1)
XMLEventReader インタフェース 構文解析を実行(つまりパーサ) java.util.Iterator として扱える =発見した要素などの構成要素の集まり (つまり、処理結果のデータでもある) hasNext()メソッド、 next()メソッド nextEvent()メソッド <doc><title>ABC</title></doc>
8
javax.xml.stream のAPI(2)
XMLInputFactory クラス XMLEventReader のインスタンスを得るための専用のクラス =それ自身は処理を実行するわけではない 会社の「受付係」、「案内係」の役割
9
Factory の「デザインパターン」 XMLInputFactory factory =
XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( source ); Factoryクラスはまず自分のインスタンスを作る Factoryのインスタンスから実際に処理を行うインスタンスを得る
10
なぜ Factory のパターンか? 「実装クラス」の実体を隠す(なぜ?) XMLEventReader reader
= new XMLEventReader( source ); とはしない XMLEventReader はインタフェース(抽象化) 実装クラスを交換可能 実行環境によって実装クラスが異なる場合にも柔軟に対応
11
必要なデータの取り出し方 XMLEventReader reader = …..; while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); System.out.println( event ); } <doc><title>ABC</title></doc>
12
XMLEvent とその仲間たち XMLEventReader がかかえるデータ
javax.xml.stream.events パッケージが提供 XMLEvent が共通のスーパインタフェース StartDocument, EndDocument StartElement, EndElement Characters, Comment Attribute など <doc><title>ABC</title></doc>
13
プログラムの基本部分(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 ) {
14
プログラムの基本部分(2) try { StreamSource source = new StreamSource( args[0] ); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( source );
15
プログラムの基本部分(3) int count=0; while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); System.out.println( "Event " + count + ":" + event ); count++; }
16
処理対象のXML文書の例 sample1.xml <document>
<title>Java and XML</title> Let's begin, now! </document>
17
実行結果 Event 0: <?xml version=“1.0” encoding=“UTF-8” ?> Event 1: <document> Event 2: Event 3:<title> Event 4: Java and XML Event 5: </title> Event 6: Let’s begin, new! Event 7: </document> Event 8: ENDDCUMENT
18
予想しにくかったイベント Event 0: 文書の開始 (StartDocument) XML文書の性質についての情報
version, encoding, standalone Event 2: 改行文字(Characters) 人間に見やすくするだけのものだが コンピュータにとってはテキスト Event 8: 文書の終了(EndDocument)
19
XML文書の例(2) sample2.xml <?xml version="1.0" encoding="UTF-8"?>
<!-- This is a comment. --> <document> <title>Java and XML</title> Let's begin, now! </document>
20
XML文書の例(2)のイベント sample2.xml
Event 0:<?xml version="1.0" encoding="UTF-8"?> Event 1:<!-- This is a comment. --> Event 2:<document> Event 3: Event 4:<title> Event 5:Java and XML Event 6:</title> Event 7:Let's begin, now! Event 8:</document> Event 9:ENDDOCUMENT
21
イベントの種類を調べる(1‐1) XMLEvent の getEventType()メソッド
System.out.println( "Event " + count + ":" + event.getEventType() ); Event 0: 7 Event 1: 1 Event 2: 4
22
イベントの種類を調べる(1‐2) イベントタイプの定数値と比較
private static String typeToString( int type ) { switch( type ) { case XMLEvent.START_DOCUMENT: return "StartDocument"; : case XMLEvent.CHARACTERS: return "Caracters"; default: return "Others"; }
23
XMLEventの種類の判定(その2) XMLEvent に定義されたメソッド
isStartElement() など boolean型の返り値 if( event.isStartDocument() ) { return "Start Document”; } else if( event.isEndDocument() ) { return "End Document"; :
24
各イベントごとのメソッド StartDocument sdevent; String version = sdevent.getVersion(); return "Start Document:version=" + version; if( event.isStartDocument() ) { String version = ((StartDocument)event).getVersion(); }
25
各イベントごとのメソッド(2) Characters テキストの内容 getData()
改行・空白のみかの判定 isWhiteSpace() if( event.isCharacters() ) { String data=""; if( ((Characters)event).isWhiteSpace() ) data = "White Space"; else data = ((Characters)event).getData(); return "Text:" + data;
26
補足:キャスト演算子( )1 データの型を変える働き なぜ型を変える必要が? 1つのデータが異なる型に同時になることはないはず 例)
補足:キャスト演算子( )1 データの型を変える働き なぜ型を変える必要が? 1つのデータが異なる型に同時になることはないはず 例) int x; String s; x = s; // エラー
27
補足:キャスト演算子( )2 型の継承関係 – 1つのデータが複数の型で表現される
補足:キャスト演算子( )2 親クラス 子クラス 型の継承関係 – 1つのデータが複数の型で表現される 例) Characters extends XMLEvent Characters は XMLEvent から「派生」 Characters は XMLEvent でもある! Characters cs1; XMLEvent xe = cs1; //キャストは省略可 Characters cs2 = (Characters)xe; //必ず必要
28
補足:キャスト演算子( )3 XMLEvent xe ; xe.isWhiteSpace(); // このままでは間違い
補足:キャスト演算子( )3 XMLEvent xe ; xe.isWhiteSpace(); // このままでは間違い Characters cs = (Characters)xe; cs.isWhiteSpace(); // これは正しい 上と同じ内容を省略して書くと XMLEvent xe; ((Characters)xe).isWhiteSpace();
29
各イベントごとのメソッド(3) StartElement 要素の名前 getName()
開始タグ内の属性リスト getAttributes() 属性を持つ要素の例 <image source="java.png" height="400" > </image>
30
属性の処理の方法(1) 属性 Attribute も XMLEvent Attributeは StartElementの内部に存在
(XMLEventReaderから直接取り出せない) Attribute の個数・順序は任意 再度 java.util.Iterator が登場
31
属性の処理の方法(2) java.util.Iterator 複数のデータを1個ずつ順にたどる (配列のように「何番目」の指定はない)
Iterator it; while( it.hasNext() ) { Object obj = it.next(); }
32
属性の処理の方法(3) Iterator からの取り出しせる型は任意 Object 型を Attribute に「キャスト」する
Object obj = it.next(); Attribute attr = (Attribute)obj; Attribute 属性の名前 getName(); 属性の値 getValue();
33
属性の処理の方法(4) while( it.hasNext() ) { Object obj = it.next(); if( obj instanceof Attribute ) { Attribute attr = (Attribute)obj; String name = attr.getName().toString(); String value = attr.getValue(); System.out.println( name + "=" + value ); }
34
前回のサンプルの解説 sample3.xml <document>
<title>Java and XML</title> Let's begin, now! <image source="java.png“ height="400" width="512" /> </document>
35
属性処理の結果 属性の登場順序は意味を持たない height=400 source=java.png width=512
登場順ではなくアルファベット順?
36
目標1:要素の総数 後で必要になる情報を記憶する(変数に) int allCount=0; // 全イベントの個数を記憶
int eleCount=0; // 要素(開始タグ)の個数を記憶 while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); allCount++; if( event.isStartElement() ) { eleCount++; }
37
目標2:要素ごとの数(1) 後で必要になる情報を記憶する(テーブルに) 複数のデータを記憶
java.util.Collection, java.util.List, java.util.Set 複数のペアのデータの表 java.util.Map (キーと値、キー全体は Set ) キー <document> <tytle> <image> <text> 値 1 2 4
38
目標2:要素ごとの数(2) 変数ではなく Mapを用意 Map<String,Integer> map
= new HashMap<String,Integer>(); while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); if( event.isStartElement() ) { String name = ((StartElement)event) .getName().toString(); saveToTable( name, map ); }
39
目標2:要素ごとの数(3) Mapへの格納方法 // 既に格納されている時ー 値を1増やす
// 既に格納されている時ー 値を1増やす if( map.containsKey( name ) ) { Integer i = map.get( name ); map.put( name, new Integer( i+1 ) ); } // 格納されていないー新たに値1で格納 else { map.put( name, new Integer( 1 ) );
40
目標2:要素ごとの数(4) Mapに記憶された値の利用 Set<String> keys = map.keySet();
Iterator<String> it = keys.iterator(); while( it.hasNext() ) { String key = it.next(); Integer value = map.get( key ); System.out.println( key + "=" + value ); }
41
補足:拡張 forループの利用 Collection の処理を簡潔に記述
Set<String> keys = map.keySet(); for( String key : keys ) { Integer value = map.get( key ); System.out.println( key + "=" + value ); } カウンタ変数、Iterator は表に出ない
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.