Download presentation
Presentation is loading. Please wait.
1
第5回 2007年5月25日 応用Java (Java/XML)
2
前回までやったこと 「XMLパーサ」-- Java でXMLを処理 javax.xml.stream パッケージのパーサ
イベントの種類の調べる 空白文字のチェック 属性の処理 応用(1) – テーブルの利用 「要素の出現回数を調べる」 java.util.Map, java.util.Set
3
本日(5/25)の講義内容 javax.xml.stream の処理の応用(2) フィルタ的な処理
MS Office のXMLを解析する java.util.Collection のフレームワーク Set, HashSet, SortedSet Map, HashMap, TreeMap
4
(復習) パッケージとAPI javax.xml.stream XMLEventReader インタフェース
XMLInputFactory クラス javax.xml.stream.events XMLEvent インタフェース サブインタフェース群 StartDocument, EndDocument, StartElement, EndElement, Characters
5
javax.xml.stream のAPI(1)
XMLEventReader インタフェース 構文解析を実行(つまりパーサ) java.util.Iterator として扱える =発見した要素などの構成要素の集まり (つまり、処理結果のデータでもある) hasNext()メソッド、 next()メソッド nextEvent()メソッド <doc><title>ABC</title></doc>
6
javax.xml.stream のAPI(2)
XMLInputFactory クラス XMLEventReader のインスタンスを得るための専用のクラス =それ自身は処理を実行するわけではない 会社の「受付係」、「案内係」の役割
7
Factory の「デザインパターン」 XMLInputFactory factory =
XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( source ); Factoryクラスはまず自分のインスタンスを作る Factoryのインスタンスから実際に処理を行うインスタンスを得る
8
必要なデータの取り出し方 XMLEventReader reader = …..; while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); System.out.println( event ); } <doc><title>ABC</title></doc>
9
XMLEvent とその仲間たち XMLEventReader がかかえるデータ
javax.xml.stream.events パッケージが提供 XMLEvent が共通のスーパインタフェース StartDocument, EndDocument StartElement, EndElement Characters, Comment Attribute など <doc><title>ABC</title></doc>
10
プログラムの基本部分(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 ) {
11
プログラムの基本部分(2) try { StreamSource source = new StreamSource( args[0] ); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLEventReader reader = factory.createXMLEventReader( source );
12
プログラムの基本部分(3) int count=0; while( reader.hasNext() ) { XMLEvent event = reader.nextEvent(); System.out.println( "Event " + count + ":" + event ); count++; }
13
処理対象のXML文書の例 sample1.xml <document>
<title>Java and XML</title> Let's begin, now! </document>
14
実行結果 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
15
XMLEventの種類の判定 XMLEvent に定義されたメソッド isStartElement() など boolean型の返り値
if( event.isStartDocument() ) { return "Start Document”; } else if( event.isEndDocument() ) { return "End Document"; :
16
各イベントごとのメソッド StartDocument sdevent; String version = sdevent.getVersion(); return "Start Document:version=" + version; if( event.isStartDocument() ) { String version = ((StartDocument)event).getVersion(); }
17
各イベントごとのメソッド(2) Characters テキストの内容 getData()
改行・空白のみかの判定 isWhiteSpace() if( event.isCharacters() ) { String data=""; if( ((Characters)event).isWhiteSpace() ) data = "White Space"; else data = ((Characters)event).getData(); return "Text:" + data;
18
各イベントごとのメソッド(3) StartElement 要素の名前 getName()
開始タグ内の属性リスト getAttributes() 属性を持つ要素の例 <image source="java.png" height="400" > </image>
19
前回の例:要素ごとの数(1) 後で必要になる情報を記憶する(テーブルに) 複数のデータを記憶
java.util.Collection, java.util.List, java.util.Set 複数のペアのデータの表 java.util.Map (キーと値、キー全体は Set ) キー <document> <tytle> <image> <text> 値 1 2 4
20
前回の例:要素ごとの数(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 ); }
21
前回の例:要素ごとの数(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 ) );
22
前回の例:要素ごとの数(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 ); }
23
補足:拡張 forループの利用 Collection の処理を簡潔に記述
Set<String> keys = map.keySet(); for( String key : keys ) { Integer value = map.get( key ); System.out.println( key + "=" + value ); } カウンタ変数、Iterator は表に出ない
24
フィルタ的な処理の実現 「フィルタ」とは? 与えられた入力内容を変換して出力 入力=>[処理内容]=>出力 例: 一部分の取り出し 並べ替え
特定のパターンの検出 特定のパターンの変換
25
今回の目的(1) 平文のテキスト部分を取り出す 特定の名前の要素を取り出す 特定の名前の要素名を変換する
26
平文テキストの取り出し Characters のイベントを処理 getData()メソッドで内容を取り出す
if( event.isCharacters() ) { Characters chars = (Characters)event; if( !chars.isWhiteSpace() ) { String text = chars.getData(); System.out.println( text ); }
27
特定の名前の要素を取り出す(1) 対象はあらかじめテーブルに記憶 Map<String,String> map
= new TreeMap<String,String>(); map.put( "document" , "body" ); map.put( "title" , "h1" ); map.put( ":text" , "p" );
28
特定の名前の要素を取り出す(2) startElement, endElementを処理 getName() メソッドでチェック
StartElement se; String name = se.getName().toString(); if( map.containsKey( name ) ) { String value = map.get( name ); System.out.println( "<" + value + ">" ); }
29
補足1)イベントの場合分け 処理をメソッドに分割する工夫 XMLEvent event = reader.nextEvent();
if( event.isStartElement() ) { startElement( (StartElement)event ); } else if( event.isEndElement() ) { endElement( (EndElement)event ); } :
30
補足2)「名前空間」 要素などの名前の衝突を避ける工夫 「名前空間(Namespace)」=「住所」 URN,URI で表現
xmlns:ns= 「省略形」として「プレフィックス」 xmlns:v="urn:schemas-microsoftcom:vml" : <v:ab> abcd </v:ab>
31
補足3)QName javax.namespace.Qname クラス 正式なURIを含む情報を定められた形式で記憶
getLocalPart() -- 名前空間を含まない部分の名前 getPrefix() – 文書内のプレフィックスの名前
32
さらに応用) MS Office のXML MicroSoft Office 2007 からファイルの保存形式の標準は XML
複数の XMLを ZIP形式で保存 word -+- document.xml +- fontTable.xml +- settings.xml +- styles.xml +- WebSettings.xml
33
補足) ZIP と Jar コマンド Jar ( Java Archive ) ファイルの保存形式はZIPを採用
t オプション – 内容を調べる x オプション – 実際に展開 使用例) jar tvf Java.docx jar xvf Java.docx
34
補足) java.util.zipパッケージ ZIP形式のファイルを直接処理する ZipFile クラス – ZIP形式のファイル
ZipEntry クラス – 格納された個々のファイルやディレクトリ ZipEntry の集まりは java.util.Enumeration (古いスタイルだが、取り扱いは java.util.Iterator とほぼ同じ)
Similar presentations
© 2024 slidesplayer.net Inc.
All rights reserved.