36
課題1 CD アルバムデータを入力するプログラムの作成 .................................................. 2 1.課題の概要................................................................................................................... 2 リスト1 CDList.xml ................................................................................................... 2 2.開発手順 ...................................................................................................................... 4 図2 JAXB による開発手順 ......................................................................................... 4 3.プログラム実行イメージ............................................................................................. 5 リスト2 プログラム実行イメージ .............................................................................. 5 リスト3 プログラム実行イメージ .............................................................................. 5 4.スキーマ定義 ............................................................................................................... 6 図3 XML Schema のツリー構造(抜粋).................................................................. 6 5.スキーマ定義の作成 .................................................................................................... 7 参考 要素の順番について ............................................................................................. 8 参考 要素や属性のデータ型について........................................................................... 9 リスト4 CDList.xsd.................................................................................................. 10 6.環境設定とスキーマ定義のコンパイル ......................................................................11 リスト5 スキーマ定義のコンパイル..........................................................................11 7.プログラムの全体構成............................................................................................... 12 図4 スキーマ定義から生成されるクラスとそのメソッド(抜粋)の関連図........... 13 図5 プログラムの全体の流れ.................................................................................... 14 8.プログラムの詳細説明............................................................................................... 15 8.1 クラスのインポートと引数チェック .......................................................... 15 8.2 入力ードの処理 ........................................................................................... 17 8.2.1 要素属性の作成と設定......................................................................... 17 8.2.2 ファイルへ書き出し ................................................................................ 24 8.2.3 例外処理 .................................................................................................. 25 8.3 編集モードの処理 ........................................................................................... 26 8.3.1 要素属性の取得と設定......................................................................... 26 .プログラムのコンパイル........................................................................................... 30 リスト6 プログラムのコンパイル ............................................................................ 30 10.コーデングリスト.................................................................................................. 31 リスト7 CDAlbum.java............................................................................................ 31

課題1 - 日本電子専門学校unno/XML/text_pat2_09.pdf · 2007-02-03 · 3 XML プログラミングにはいろいろな方法があります。課題1では、JAXB(The Java

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

目 次 課題1 CDアルバムデータを入力するプログラムの作成 .................................................. 2 1.課題の概要................................................................................................................... 2 リスト1 CDList.xml................................................................................................... 2 2.開発手順 ...................................................................................................................... 4 図2 JAXBによる開発手順 ......................................................................................... 4 3.プログラム実行イメージ .............................................................................................5 リスト2 プログラム実行イメージ .............................................................................. 5 リスト3 プログラム実行イメージ .............................................................................. 5 4.スキーマ定義 ............................................................................................................... 6 図3 XML Schemaのツリー構造(抜粋).................................................................. 6 5.スキーマ定義の作成 .................................................................................................... 7 参考 要素の順番について .............................................................................................8 参考 要素や属性のデータ型について........................................................................... 9 リスト4 CDList.xsd.................................................................................................. 10 6.環境設定とスキーマ定義のコンパイル ......................................................................11 リスト5 スキーマ定義のコンパイル..........................................................................11 7.プログラムの全体構成...............................................................................................12 図4 スキーマ定義から生成されるクラスとそのメソッド(抜粋)の関連図........... 13 図5 プログラムの全体の流れ.................................................................................... 14 8.プログラムの詳細説明...............................................................................................15 8.1 クラスのインポートと引数のチェック ..........................................................15 8.2 入力モードの処理 ...........................................................................................17 8.2.1 要素・属性の作成と設定......................................................................... 17 8.2.2 ファイルへ書き出し ................................................................................ 24 8.2.3 例外処理 .................................................................................................. 25 8.3 編集モードの処理 ...........................................................................................26 8.3.1 要素・属性の取得と設定......................................................................... 26 9.プログラムのコンパイル ...........................................................................................30 リスト6 プログラムのコンパイル ............................................................................ 30

10.コーディングリスト.................................................................................................. 31 リスト7 CDAlbum.java............................................................................................31

2

第2部 CD製作会社のマーケティング調査 課題1 CDアルバムデータを入力するプログラムの作成 1.課題の概要

まず、CD製作会社が CDアルバムデータを入力するプログラムを作成します。コマンドプロンプトから CDアルバムの情報を入力して、リスト1のような XMLを作成するプログラムです。この XMLをツリー構造にすると図1のようになります。 リスト1 CDList.xml(太字は入力データ)

1: <?xml version="1.0" encoding="Shift_JIS"?> 2: <CDList xmlns="urn:educationproject:cdlist"> 3: <CD> 4: <Title>CDタイトル名</Title> 5: <Artist>アーティスト名</Artist> 6: <Release>2004-06-30</Release> 7: <Image>artist.jpg</Image> 8: <MusicList> 9: <Music Time="777" Title="タイトル 1" /> 10: <Music Time="171" Title="タイトル 2" /> 11: </MusicList> 12: </CD> 13: </CDList>

図1 CDList.xmlのツリー構造

CDList要素

Title要素

Artist要素

Release要素

Image要素

MusicList要素

Time属性

Title属性

Music要素

CD要素

3

XML プログラミングにはいろいろな方法があります。課題1では、JAXB(The Java Architecture for XML Binding)を使用します。JAXBとは、データバインディングと言って Javaと XMLをマッピング(対応付け)してプログラムを簡単にしようとするツールです。 例えば、リスト1の XMLを作成する場合、入力した文字列をタグで囲んでそのままファイルに書き出す方法もあるでしょう。しかしその方法では、間違ったタグ名や意図しない

データなどのミスがあってもコンパイル・実行出来てしまいます。 JAXBでは、XMLの構造やデータ型を定義するスキーマをあらかじめ作成し、そのスキーマ定義を元にして、Javaのクラスを自動生成させます。これにより Javaと XMLがマッピングされ、XMLとしてのタグや属性を、Javaのクラスが自動的に挿入してくれます。

4

2.開発手順

実際の開発手順は図2のようになります。最初にスキーマ定義を作成し、そのスキーマ

定義をコンパイルして、Javaによるクラス定義を生成します。そのクラス定義を使用してプログラムを作成し、プログラムを実行します。 スキーマ定義には DTDや XML Schemaなど複数存在しますが、今回は XML Schemaを使用します。 図2 JAXBによる開発手順

スキーマ定義

スキーマ定義のコンパ

イル

自動生成クラスを使用

してプログラムを作成

Javaによるクラス 定義(自動生成)

プログラム実行 XML

5

3.プログラム実行イメージ

CD アルバムデータの入力を行い、入力した内容を編集出来るプログラムを作成します。リスト2とリスト3がそれぞれ入力モードと編集モードのプログラム実行イメージです。 リスト2 プログラム実行イメージ(入力モード:太字はコマンド入力および入力データ)

C:¥java>java CDAlbum –input >>> CDタイトル CDタイトル名 >>> アーティスト名 アーティスト名 >>> 発売日(YYYY-MM-DD) 2004-06-30 >>> イメージファイル名 artist.jpg >>> 曲名(曲名が入力されなかったら終了) タイトル 1 >>> 曲時間(mm:ss) 12:57 >>> 曲名(曲名が入力されなかったら終了) タイトル 2 >>> 曲時間(mm:ss) 2:51 >>> 曲名(曲名が入力されなかったら終了) 入力データを保存しました。 C:¥java>

リスト3 プログラム実行イメージ(編集モード:太字はコマンド入力および入力データ)

C:¥java> java CDAlbum -edit >>> CD タイトル (CDタイトル名) CDタイトル 2 >>> アーティスト名 (アーティスト名) アーティスト名 2 >>> 発売日 (2004-06-30) 2004-10-10 >>> イメージファイル名 (artist.jpg) artist2.jpg >>> 曲名 (タイトル 1) タイトル 3 >>> 曲時間 (12:57) 6:28 >>> 曲名 (タイトル 2) タイトル 4 >>> 曲時間 (02:51) 4:15 入力データを保存しました。 C:¥java>

6

4.スキーマ定義

それでは、実際に図2の手順に従ってスキーマ定義とプログラムを作成していきます。 まず、リスト1の XML を XML Schema を使用してスキーマ定義を作成します。XML Schemaのツリー構造(抜粋)は図3のようになります。 図3 XML Schemaのツリー構造(抜粋)

スキーマ定義を作成するに当たり、以下のような制限を設けることにします。 1.ルート要素名を「CDList」とする。 2.1枚の CD情報を「CD」要素に記録する。 3.「Release」要素の値は date型(YYYY-MM-DD)とする。 4.曲目情報を「MusicList」要素に記録する。 5.Music要素の「Time」属性の値は曲の長さを秒数で表し、正の整数とする。

これらの制限を元にスキーマ定義を作成します。

schema要素

complexType要素

element要素

sequence要素

name属性

type属性

name属性

type属性

ref属性

element要素

子要素がある場合

別の場所の要素定義を参照

要素を列挙

要素名

要素のデータ型(complexType要素とは排他使用)

属性のデータ型

属性名

attribute要素attribute要素 属性がある場合に列挙

子要素・属性がある場合の型定義(type属性とは排他使用)

要素を列挙

minOccurs属性

maxOccurs属性

要素の最低繰り返し回数

要素の最高繰り返し回数

7

5.スキーマ定義の作成

それでは、スキーマ定義の内容を順番に見ていくことにします。

1: <?xml version="1.0" encoding="Shift_JIS"?> XML文書の宣言です。XML Schema自体も XMLで作成しますので、この宣言が必要です。encodingの部分は文字コードを現します。Windowsでは通常シフト JISという文字コードが使用されています。

1: <xs:schema 2: xmlns:xs="http://www.w3.org/2001/XMLSchema" 3: targetNamespace="urn:educationproject:cdlist" 4: xmlns="urn:educationproject:cdlist">

ルート要素の宣言です。XML Schemaでは、ルート要素名は「schema」と決まっています。 「schema」の前に「xs:」という文字が付いています。これは名前空間接頭辞と呼ばれるものです。 名前空間とは、いろいろな定義で使用される要素や属性などの名前を一意に表現するた

めのものです。今回の場合、2行目に「xmlns:xs="http://www.w3.org/2001/XMLSchema"」とありますが、「xs:」と付いた場合には、その定義は「http://www.w3.org/2001/XMLSchema」で定義されているということです。例えば、 Java で文字列を表示する場合に「System.out.print」というメソッドを使用しますが、単に「print」と書くと、他のクラスに同じ「print」というメソッドがある場合に区別出来ません。ここでの「System.out.」と似たような考え方です。 3行目の「targetNamespace="urn:educationproject:cdlist"」は、このスキーマに従うXML の名前空間を表しています。JAXB で XML Schema をコンパイルした場合には、「educationproject¥cdlist」の構造でクラスを生成します。ここで「urn:」と付いています。URL(Uniform Resource Locator)は皆さんもご存知だと思いますが、URN(Universal Resource Name)も似たようなものです。ただし、URLは場所を指しますが、URNは名前です。つまり URLはWWWサーバの場所が含まれていますので、WWWサーバの場所が変わるとURLも変わってしまいます。しかし URNは名前ですので、世界で唯一の名前を付けておけば、サーバの場所などに関係無く使い続けることが可能です。 4行目の「xmlns="urn:educationproject:cdlist"」は2行目と似ています。何が違うかと言うと、2行目は XML Schema自体の宣言だったのに対し、4行目はスキーマ定義の内容に対する宣言になります。ここでは「xs:」のような名前空間の接頭辞が付いていません。これを付けないと既定の名前空間となり、このスキーマ定義は全てこの名前空間を使用す

るということになります。

8

1: <xs:element name="CDList">

これからが XMLの要素や属性の定義です。 「element」は要素の定義です。「name」属性が要素名です。つまりこの定義は、XMLのルート要素を定義しています。

1: <xs:complexType> 「complexType」は子要素・属性を持つことを意味します。

1: <xs:sequence> 2: <xs:element ref="CD" minOccurs="0" maxOccurs="unbounded" /> 3: </xs:sequence>

「sequence」は子要素の順番を定義します。「sequence」の中の「element」がその順番に書き出されなければならないことを意味します。 ただし、ここでは「element」が1つしか存在しませんので、順番を指定する必要は無いように思われますが、「complexType」を宣言した場合で子要素(「element」)がある場合、以下の3つのうちのいずれかを指定する必要があるのです。 参考 要素の順番について

sequence 定義されている要素をその順番で出現させる choice 定義されている要素のうち1つを出現させる all 全てを1回出現させる

ここでは、「element」に「name」属性が指定されていません。これは、「name」属性の代わりに「ref」属性を指定して、別の場所で定義した「<xs:element name="CD">」という要素を参照することを意味しています。なぜこのようなことをするかと言うと、要素の

階層が深くなると、非常に分かりづらい定義になってしまうからです。 「minOccurs」と「maxOccurs」属性は、同じ要素が複数回現れる場合に「要素を最低何回記述しなければならないか」「要素を最高何回記述しても良いか」を意味します。上限

が無い場合には「unbounded」を指定します。指定しなかった場合の既定値は「minOccurs="1" maxOccurs="1"」となります。 同様に、「CD」要素や「Title」要素などの要素を定義します。

1: <xs:element name="Title" type="xs:string" /> 「type」属性は、要素や属性のデータ型を指定します。主なデータ型は次の通りです。

9

参考 要素や属性のデータ型について

string 文字列 boolean 論理型(trueか false又は 1か 0) integer 整数 nonNegativeInteger 0以上の整数 nonPositiveInteger 0以下の整数 float 単精度浮動小数 double 倍精度浮動小数 date 日付(YYYY-MM-DD) time 時刻(hh:mm:ss)

属性定義は次のような記述になります。

1 <xs:attribute name="Time" type="xs:nonNegativeInteger" /> 「attribute」は属性の定義です。「name」属性が属性名です。「type」属性は前述のデータ型です。 これで、XML Schemaを使用したスキーマ定義が作成出来ました。

10

リスト4 CDList.xsd(太字は任意設定値) 1: <?xml version="1.0" encoding="Shift_JIS"?> 2: <xs:schema 3: xmlns:xs="http://www.w3.org/2001/XMLSchema" 4: targetNamespace="urn:educationproject:cdlist" 5: xmlns="urn:educationproject:cdlist"> 6: <xs:element name="CDList"> 7: <xs:complexType> 8: <xs:sequence> 9: <xs:element ref="CD" minOccurs="0" maxOccurs="unbounded" /> 10: </xs:sequence> 11: </xs:complexType> 12: </xs:element> 13: 14: <xs:element name="CD"> 15: <xs:complexType> 16: <xs:sequence> 17: <xs:element ref="Title" /> 18: <xs:element ref="Artist" /> 19: <xs:element ref="Release" /> 20: <xs:element ref="Image" /> 21: <xs:element ref="MusicList" /> 22: </xs:sequence> 23: </xs:complexType> 24: </xs:element> 25: 26: <xs:element name="Title" type="xs:string" /> 27: <xs:element name="Artist" type="xs:string" /> 28: <xs:element name="Release" type="xs:date" /> 29: <xs:element name="Image" type="xs:string" /> 30: <xs:element name="MusicList"> 31: <xs:complexType> 32: <xs:sequence> 33: <xs:element ref="Music" minOccurs="1" maxOccurs="unbounded" /> 34: </xs:sequence> 35: </xs:complexType> 36: </xs:element> 37: 38: <xs:element name="Music"> 39: <xs:complexType> 40: <xs:attribute name="Time" type="xs:nonNegativeInteger" /> 41: <xs:attribute name="Title" type="xs:string" /> 42: </xs:complexType> 43: </xs:element> 44: </xs:schema>

11

6.環境設定とスキーマ定義のコンパイル

次は、スキーマ定義のコンパイルです。 まず、JAXBをインストールします。JAXBは以下のホームページの Java Web Services Developer Packの中に含まれています。ここから最新版の v1.4をダウンロードしてインストールします。(ここでは、インストール先を C:¥jwsdp-1.4として説明します。) http://java.sun.com/webservices/downloads/webservicespack.html コンパイルする前に環境設定が必要です。以下の手順で環境変数を定義します。 1.PATHに C:¥jwsdp-1.4¥jaxb¥binを追加する。 2.CLASSPATHに以下の内容を設定(追加)する。 C:¥jwsdp-1.4¥jaxb¥lib¥jaxb-api.jar C:¥jwsdp-1.4¥jaxb¥lib¥jaxb-impl.jar C:¥jwsdp-1.4¥jaxb¥lib¥jaxb-libs.jar C:¥jwsdp-1.4¥jwsdp-shared¥lib¥jax-qname.jar C:¥jwsdp-1.4¥jwsdp-shared¥lib¥namespace.jar C:¥jwsdp-1.4¥jwsdp-shared¥lib¥relaxngDatatype.jar C:¥jwsdp-1.4¥jwsdp-shared¥lib¥xsdlib.jar C:¥jwsdp-1.4¥jaxp¥lib¥jaxp-api.jar C:¥jwsdp-1.4¥jaxp¥lib¥endorsed¥dom.jar C:¥jwsdp-1.4¥jaxp¥lib¥endorsed¥sax.jar C:¥jwsdp-1.4¥jaxp¥lib¥endorsed¥xercesImpl.jar

上記の環境設定が終了したら、xjcコマンドでコンパイルします。引数はリスト2のスキーマ定義ファイル名です。 リスト5 スキーマ定義のコンパイル(太字はコマンド入力)

C:¥java>xjc CDList.xsd コンパイルが終了すると、カレントフォルダ内の educationproject¥cdlist 以下にクラス定義が自動生成されます。細かいファイルの説明は省略しますが、スキーマ定義の各要素

名に対応したファイルとそれらのクラスに必要なファイルが自動生成されています。 この時点では、クラス定義が生成されるだけで、クラス定義のコンパイルは行われませ

ん。クラス定義のコンパイルはプログラムのコンパイルと併せて行います。

12

7.プログラムの全体構成

スキーマ定義のコンパイルにより、図2のようなクラスとメソッドが生成されます。こ

れらのクラスを使用してプログラムします。各メソッドの使い方は次のようになります。 ・XMLのルート要素(CDList要素)を ObjectFactoryクラスの createメソッドで作成します。 ・スキーマで複数要素(つまり要素数が不定である)として定義されている要素(CD要素とMusic要素)も createメソッドで作成します。これらの要素は、その親要素に、コンテナとなる List 型のオブジェクトが用意されますので、そのコンテナに、必要な数だけ要素を追加(addメソッド)する形で複数要素を構成します。 ・子要素を持たない末端の要素(Title 要素など)や属性(Time 属性など)については、

get/setメソッドで値を取得/設定できます。 ・その他、子要素を持つ要素(MusicList要素)は、その要素を createメソッドで作成し、そしてその親要素に用意されている setメソッドを使用し、設定します。

13

図4 スキーマ定義から生成されるクラスとそのメソッド(抜粋)の関連図

ObjectFactoryクラス CDList createCDList() CD createCD() MusicList createMusicList() Music createMusic()

CDListクラス java.util.List getCD()

CDクラス java.lang.String getTitle() void setTitle(java.lang.String value) java.lang.String getArtist() void setArtist(java.lang.String value) java.util.Calendar getRelease() void setRelease(java.util.Calendar value) java.lang.String getImage() void setImage(java.lang.String value) void setMusicList(MusicList value)

MusicListクラス java.util.List getMusic()

Musicクラス java.lang.String getTitle() void setTitle(java.lang.String value) java.math.BigInteger getTime() void setTime(java.math.BigInteger value)

要素の生成

追加(.add) 取得(.get)

追加(.add) 取得(.get)

要素の設定・

取得

属性の設定・

取得

要素の設定

14

プログラムの全体の流れは図5のようになります。 図5 プログラムの全体の流れ

8.1 クラスのインポートと引数のチェック

8.2.1 要素・属性の作成と設定

8.2.2 ファイルへ書き出し

8.3 編集モードの処理

8.3.1 要素・属性の取得と設定

以下、入力モードの処理と同様

8.2.3 例外処理

15

8.プログラムの詳細説明

ここからは Javaによる、CDアルバムデータ入力プログラムの作成です。それでは、プログラムを順番に作成していきます。 8.1 クラスのインポートと引数のチェック

まず、必要なクラスをインポートします。その後、メインプログラムで引数のチェック

をして、入力・編集のそれぞれのモードの処理をします。

1: import javax.xml.bind.*; 2: import java.io.*; 3: import java.math.*; 4: import java.text.*; 5: import java.util.*;

JAXB を使用する場合、javax.xml.bind.*をインポートします。その他の import 文は、文字入力やファイル出力等のために必要です。

1: import educationproject.cdlist.*; スキーマコンパイラが生成したクラス定義をインポートします。これは、スキーマ定義

CDList.xsdの targetNamespace="urn:education:project:cdlist"のURNの部分と同じになります。尚、「:」を「.」に変更します。

1: public class CDAlbum { 2: public static void main(String[] args) { 3: String str; 4: FileOutputStream fos = null;

CDAlbumというクラス名でプログラムを作成します。このクラス名は CDAlbumである必要はありませんが、Javaではクラス名とファイル名を同じにする必要がありますので、ファイル名は「クラス名.java」としなければいけません。尚、スキーマ定義 CDList.xsdの要素名と同じにすると、スキーマ定義が生成したクラス名と同じになりエラーになりま

すので、注意が必要です。 mainメソッドは Javaが最初に実行するメソッドです。strや fosは文字列操作やファイル出力の時に使用する変数です。

16

1: if (args.length != 1) { 2: System.out.println("引数を入力してください。"); 3: System.out.println(" -input : 入力"); 4: System.out.println(" -edit : 編集"); 5: return; 6: }

main メソッドには、コマンドラインパラメータが渡されます。args.length で、そのパラメータの個数をチェックし、1個以外の場合にはメッセージを出力して終了します。 今回は、「-input」が入力の場合のパラメータ、「-edit」が編集の場合のパラメータとします。

1: if (args[0].equals("-input")) { 2: // 入力モードの処理

3: else if (args[0].equals("-edit")) { 4: // 編集モードの処理 5: }

コマンドラインパラメータが「-input」(入力モード)の場合と「-edit」(編集モード)の場合で処理を分けます。

17

8.2 入力モードの処理

入力モードの処理です。ここからが、JAXBを使用したプログラムとなります。要素・属性の作成と設定、ファイルへの書き出し、例外処理の3つのブロックに分けて説明します。 8.2.1 要素・属性の作成と設定

まず tryブロック内の主な構造を示します。

// JAXBContext,ObjectFactoryオブジェクトの作成 ···················① JAXBContext jc = JAXBContext.newInstance("educationproject.cdlist"); ObjectFactory of = new ObjectFactory(); // CDList要素の作成 ·····························································② CDList cdlist = of.createCDList(); // 複数の子要素のコンテナとなる Listオブジェクトの取得 ·········③ List list1 = cdlist.getCD(); // CD要素の作成 ··································································④ CD cd = of.createCD(); // Title要素の設定 ································································⑤ cd.setTitle(str); // Artist要素の設定 ·······························································⑥ cd.setArtist(str); // Release要素の設定 ····························································⑦ for ( ; ; ) { try { cd.setRelease(cal); break; } catch (ParseException e) { System.out.println("発売日の入力に誤りがあります。"); } }

18

// Image要素の設定 ······························································⑧ cd.setImage(str); // MusicList要素の作成 ·························································⑨ MusicList musiclist = of.createMusicList(); // 複数の子要素のコンテナとなる Listオブジェクトの取得 List list2 = musiclist.getMusic(); // Music要素の複数入力 ························································⑩ for ( ; ; ) { // 曲名が入力されなかったら終了 if (str.equals("")) break; // Music要素の作成 Music music = of.createMusic(); // Title属性の設定 music.setTitle(str); // 曲時間の入力 ·································································⑪ for ( ; ; ) { try { // Time属性の設定 music.setTime(BigInteger.valueOf(sec)); break; } catch (ParseException e) { System.out.println("曲時間の入力に誤りがあります。"); } } // Music要素をコンテナに格納 ············································⑫ list2.add(music); } // MusicList要素の設定 ·························································⑬ cd.setMusicList(musiclist); // CD要素をコンテナに格納 ···················································⑭ list1.add(cd);

以降、プログラムの詳細説明です。

19

① JAXBContext,ObjectFactoryオブジェクトの作成 1: JAXBContext jc = 2: JAXBContext.newInstance("educationproject.cdlist");

最初に javax.xml.bind.JAXBContext の newInstance メソッドを使用して、JAXBContextオブジェクトを生成します。その際、メソッドの引数には、スキーマコンパイラが生成したクラスのパッケージ名を指定します。 XML の入出力や妥当性の検証を行う際に、JAXBContext オブジェクトが必要ですので、この行は必須となります。

1: ObjectFactory of = new ObjectFactory(); スキーマコンパイラが生成した XML の要素や属性に対応するオブジェクトを新規に生成するためには ObjectFactory オブジェクトが必要です。ObjectFactory オブジェクトのcreate<要素名・属性名>というメソッドで要素や属性に対応するオブジェクトを生成します。 ② CDList要素の作成

1: CDList cdlist = of.createCDList(); このように ObjectFactory オブジェクトを使用して、ルート要素(CDList)のオブジェクトを生成します。 ③ 複数の子要素のコンテナとなる Listオブジェクトの取得

1: List list1 = cdlist.getCD(); XML Schemaの定義により子要素が複数存在する場合には、親要素のオブジェクトからget<子要素名>メソッドで java.util.Listオブジェクトを取得します。この Listオブジェクトに add メソッドで子要素を追加していきます。今回は、1回の入力で CD 要素は1個となりますが、複数存在する可能性がある場合には同様の処理となります。 ④ CD要素の作成

1: CD cd = of.createCD(); CDListオブジェクトと同様で、ObjectFactoryオブジェクトを使用して CD要素のオブジェクトを生成しています。CD要素の子要素や属性は、CD要素オブジェクトの set<要素名・属性名>メソッドで設定します。 ⑤ Title要素の設定

1: BufferedReader br = 2: new BufferedReader(new InputStreamReader(System.in));

コマンドラインから文字を入力する準備として、BufferedReaderオブジェクトを用意し

20

ています。このオブジェクトの readLineメソッドで入力された文字を受け取ります。

1: for ( ; ; ) { 2: System.out.println(">>> CD タイトル"); 3: str = br.readLine(); 4: if (!str.equals("")) break; 5: } 6: cd.setTitle(str);

System.out.printlnメソッドで文字列を表示して、CDタイトルを入力します。タイトルは必ず入力させるため、空文字列でなくなるまで for文で無限ループしています。文字列が入力された場合には、無限ループから抜け、CDオブジェクトの setTitleメソッドを使用し、Title要素に、入力された文字列を設定しています。 ⑥ Artist要素の設定

1: for ( ; ; ) { 2: System.out.println(">>> アーティスト名"); 3: str = br.readLine(); 4: if (!str.equals("")) break; 5: } 6: cd.setArtist(str);

CDタイトルと同様に、アーティスト名を入力します。 ⑦ Release要素の設定

1: for ( ; ; ) { 2: System.out.println(">>> 発売日 (YYYY-MM-DD)"); 3: str = br.readLine(); 4: Calendar cal = Calendar.getInstance(); 5: DateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); 6: try { 7: cal.setTime(formater.parse(str)); 8: cd.setRelease(cal); 9: break; 10: } catch (ParseException e) { 11: System.out.println("発売日の入力に誤りがあります。"); 12: } 13: }

発売日を入力します。Release要素は date(日付)データ型です。date型の場合には、Calendarオブジェクトで設定する必要があり、今回は以下のような手順になっています。

21

1.Calendarクラスの getInstanceメソッドで Calendarオブジェクトを生成します。 2.SimpleDateFormat クラスのコンストラクタの引数に「yyyy-MM-dd」を渡し、

DateFormatオブジェクトを生成します。 3.DateFormat オブジェクトの parse メソッドの引数に入力された文字を渡し、

java.util.Date型に変換します。入力された文字列が「yyyy-MM-dd」のフォーマットに合っていない場合には、ParseException例外が発生しますので、エラーメッセージを表示します。 4.Calendarオブジェクトの setTimeメソッドの引数に変換された日付を渡し、日付を設定します。(プログラムでは、例外処理を除き、3と4が1行になっています。) 5.CDオブジェクトの setReleaseメソッドの引数に Calendarオブジェクトを渡し、日付を設定します。

⑧ Image要素の設定

1: System.out.println(">>> イメージファイル名"); 2: str = br.readLine(); 3: cd.setImage(str); 4: System.out.println("");

イメージファイル名を入力します。イメージファイル名は、空文字列を許可するために

無限ループは使用していません。 その後、空行を1行表示しています。 ⑨ MusicList要素の作成

1: MusicList musiclist = of.createMusicList(); 2: List list2 = musiclist.getMusic();

ここからは、曲データの入力です。 CDオブジェクトと同様に、ObjectFactoryオブジェクトを使用してMusicList要素のオブジェクトを生成しています。MusicList 要素にも子要素 Music が複数存在しますので、getMusicメソッドで java.util.Listオブジェクトを取得しています。 ⑩ Music要素の複数入力

1: for ( ; ; ) { 2: System.out.println(">>> 曲名"); 3: str = br.readLine(); 4: // 曲名が入力されなかったら終了 5: if (str.equals("")) break; 6: Music music = of.createMusic(); 7: music.setTitle(str);

22

Music要素を複数入力するために for文で無限ループします。曲名を入力し、空文字列であれば無限ループから抜け、入力を終了します。空文字列でなければ、Music オブジェクトを生成し、Title属性を設定します。ここでは要素ではなく属性ですが、要素と同様に set<属性名>メソッドになります。 ⑪ 曲時間の入力

1: for ( ; ; ) 2: { 3: System.out.println(">>> 曲時間 (mm:ss)"); 4: str = br.readLine(); 5: Calendar cal = Calendar.getInstance(); 6: DateFormat formater = new SimpleDateFormat("mm:ss"); 7: try { 8: cal.setTime(formater.parse(str)); 9: long sec = 10: cal.get(Calendar.MINUTE) * 60 + 11: cal.get(Calendar.SECOND); 12: music.setTime(BigInteger.valueOf(sec)); 13: break; 14: } catch (ParseException e) { 15: System.out.println("曲時間の入力に誤りがあります。"); 16: } 17: }

曲時間を入力します。Time属性は nonNegativeInteger(0以上の整数)データ型です。nonNegativeInteger型の場合には、BigIntegerオブジェクトで設定する必要があり、以下のような手順になります。 1.Calendarクラスの getInstanceメソッドで Calendarオブジェクトを生成します。 2.SimpleDateFormatクラスのコンストラクタの引数に「mm:ss」を渡し、DateFormatオブジェクトを生成します。 3.DateFormat オブジェクトの parse メソッドの引数に入力された文字を渡し、

java.util.Date型に変換します。入力された文字列が「mm:ss」のフォーマットに合っていない場合には、ParseException例外が発生しますので、エラーメッセージを表示します。

4.Calendarオブジェクトの setTimeメソッドの引数に変換された日付を渡し、日付を設定します。(プログラムでは、例外処理を除き、3と4が1行になっています。) 5.Calendarオブジェクトの getメソッドで分(MINUTE)と秒(SECOND)を取得し、秒数を計算して long型の変数に代入します。 6.BigInteger クラスの valueOf メソッドの引数に long 型の秒数を渡し、BigInteger 型

23

に変換します。 7.Musicオブジェクトの setTimeメソッドの引数に BigInteger型を渡し、秒数を設定します。(プログラムでは、6と7が1行になっています。)

⑫ Music要素をコンテナに格納

1: list2.add(music); MusicListのオブジェクトから取得した ListオブジェクトにMusic要素を追加します。 ⑬ MusicList要素の設定

1: cd.setMusicList(musiclist); CDオブジェクトにMusicListオブジェクトを設定します。 ⑭ CD要素をコンテナに格納

1: list1.add(cd); CDListオブジェクトから取得した Listオブジェクトに CD要素を追加します。 これで、データの入力と入力された文字列の設定は終了です。

24

8.2.2 ファイルへ書き出し

入力されたデータの内容を検証し、ファイルに書き出します。

1: Validator v = jc.createValidator(); 2: boolean valid = v.validateRoot(cdlist);

JAXBContext オブジェクトの createValidator メソッドで Validator オブジェクトを取得します。Validatorオブジェクトの validateRootメソッドを呼び出して、データの内容を検証します。検証でエラーになると JAXBException例外が発生します。

1: Marshaller m = jc.createMarshaller(); 2: m.setProperty(Marshaller.JAXB_ENCODING, "Shift_JIS"); 3: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 4: Boolean.TRUE);

JAXBContextオブジェクトの createMarshallerメソッドにより、Marshallerオブジェクトを取得します。JAXBでは XMLの書き出しのことをマーシャル(Marshal)といいます。逆に XMLの読み出しのことをアンマーシャル(Unmarshal)といいます。 Marshaller オブジェクトの setProperty メソッドで書き出す情報を設定しています。JAXB_ENCODINGで文字エンコーディングを指定します。ここでは、シフト JISコードを指定しています。JAXB_FORMATTED_OUTPUTで、出力する内容に改行やインデントを付加するかどうかを指定します。これを指定しないと、出力された内容に改行や子要素

の字下げが行われず、見づらい内容になります。

1: fos = new FileOutputStream("CDList.xml"); 2: m.marshal(cdlist, fos); 3: fos.close(); 4: System.out.println("入力データを保存しました。"); 5: return;

FileOutputStreamクラスのコンストラクタの引数にファイル名を指定して、ファイル出力ストリームを作成します。次にMarshallerオブジェクトのmarshalメソッドにルート要素のオブジェクトとファイル出力ストリームを指定してファイルに書き出します。最後に

ファイル出力ストリームをクローズします。 例外が発生しなかった場合には、メッセージを出力してここで終了します。

25

8.2.3 例外処理

JAXBに限らず、ファイル出力等でエラーが発生する可能性がありますので、入力モードの全ての処理を例外の対象とします。

1: try { 2: // 要素・属性の作成と設定 3: // ファイルへ書き出し 4: } catch (JAXBException e) { 5: e.printStackTrace(); 6: } catch (IOException e) { 7: e.printStackTrace(); 8: } finally { 9: try { 10: if (fos != null) fos.close(); 11: } catch (IOException e) { 12: e.printStackTrace(); 13: } 14: } 15: System.out.println("エラーが発生しました。");

JAXBでの例外 JAXBException、XMLの書き出しでの例外 IOExceptionが発生した場合に、printStackTraceメソッドでスタックトレース(プログラムのソースコードの呼び出し履歴)を表示します。その後、finally ブロックで、ファイル出力ストリームが生成されていた場合に、クローズ処理をします。ここでも例外が発生した場合にスタックトレース

を表示します。最後にメッセージを表示して終了します。

26

8.3 編集モードの処理

コマンドラインパラメータが「- edit」(編集モード)の場合の編集の処理です。入力の処理と違う部分を抜き出して説明します。 8.3.1 要素・属性の取得と設定

1: Unmarshaller unmarshaller = jc.createUnmarshaller(); 2: unmarshaller.setValidating(true);

JAXBContext オブジェクトの createUnmarshallerメソッドにより、Unmarshaller オブジェクトを取得します。編集処理では最初に XML を読み出しますので、Unmarshallerオブジェクトが必要です。 Unmarshaller オブジェクトの setValidating メソッドの引数に true を渡し、読み出すXMLを検証します。検証でエラーになると JAXBException例外が発生します。

1: CDList cdlist = 2: (CDList)unmarshaller.unmarshal(new File("CDList.xml"));

Unmarshallerオブジェクトの unmarshal メソッドの引数に File オブジェクトを渡し、ルート要素(CDList)のオブジェクトを取得します。ここでファイルが存在しない場合には、例外が発生します。

1: CD cd = (CD)cdlist.getCD().get(0); CDList要素の子要素(CD)は複数存在できますので、それらは一旦 Listオブジェクトで取得できます。CDListオブジェクトから getCDメソッドで CD要素の Listオブジェクトを取得し、getメソッドで1番目の CD要素を取得します。getメソッドで返される型はjava.lang.Object型ですので、CDオブジェクト型にキャストする必要があります。

1: System.out.println(">>> CD タイトル (" + cd.getTitle() + ")"); 2: str = br.readLine(); 3: if (!str.equals("")) cd.setTitle(str);

CDタイトルを入力します。入力処理との違いは、現在入力されているタイトルを CDオブジェクトの getTitle メソッドで取得して表示しているところと、入力された文字が空文字列で無い場合に setTitle メソッドで入力された文字を設定しているところです。もし空文字列であれば何もせず、元の文字列のままとなります。

27

1: System.out.println(">>> アーティスト名 (" + cd.getArtist() + ")"); 2: str = br.readLine(); 3: if (!str.equals("")) cd.setArtist(str);

CDタイトルと同様に、アーティスト名を入力します。

1: for ( ; ; ) { 2: DateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); 3: System.out.println(">>> 発売日 (" + 4: formater.format(cd.getRelease().getTime()) + ")"); 5: str = br.readLine(); 6: if (str.equals("")) break; 7: Calendar cal = Calendar.getInstance(); 8: try { 9: cal.setTime(formater.parse(str)); 10: cd.setRelease(cal); 11: break; 12: } catch (ParseException e) { 13: System.out.println("発売日の入力に誤りがあります。"); 14: } 15: }

発売日を入力します。入力されている発売日の表示は、DateFormatクラスの formatメソッドを使用します。このメソッドは、引数が java.util.Date 型ですので、getRelease メソッドで取得した Calendar型から java.util.Date型に変換するために、getTimeメソッドを使用しています。

1: System.out.println(">>> イメージファイル名 (" + 2: cd.getImage() + ")"); 3: str = br.readLine(); 4: if (!str.equals("")) cd.setImage(str); 5: System.out.println("");

イメージファイル名を入力します。

1: List list2 = cd.getMusicList().getMusic(); CDオブジェクトからMusicList要素のオブジェクトを取得し、getMusicメソッドでListオブジェクトを取得しています。

28

1: for (int i = 0; i < list2.size(); i++) { 2: Music music = (Music)list2.get(i);

List オブジェクトの size メソッドで Music 要素の数を取得して、その数だけループし、Music要素のオブジェクトを取得します。

1: System.out.println(">>> 曲名 (" + music.getTitle() + ")"); 2: str = br.readLine(); 3: if (!str.equals("")) music.setTitle(str);

曲名を入力します。

1: for ( ; ; ) 2: { 3: DecimalFormat df = new DecimalFormat("00"); 4: System.out.println(">>> 曲時間 (" + 5: df.format(music.getTime().longValue() / 60) + ":" + 6: df.format(music.getTime().longValue() % 60) +")"); 7: str = br.readLine(); 8: if (str.equals("")) break; 9: Calendar cal = Calendar.getInstance(); 10: DateFormat formater = new SimpleDateFormat("mm:ss"); 11: try { 12: cal.setTime(formater.parse(str)); 13: long sec = 14: cal.get(Calendar.MINUTE) * 60 + 15: cal.get(Calendar.SECOND); 16: music.setTime(BigInteger.valueOf(sec)); 17: break; 18: } catch (ParseException e) { 19: System.out.println("曲時間の入力に誤りがあります。"); 20: }

発売日を入力します。入力されている曲時間の表示は、DecimalFormatクラスの formatメソッドを使用します。このメソッドは、引数が long型又は double型ですので、getTimeメソッドで取得した BigInteger型から long型に変換するために、longValueメソッドを使用し、その数値から 60で割った商と余りを求め、分と秒に分けて表示しています。 これ以降は、入力処理と同様です。

29

尚、今回の処理によって書き出された XMLは、日本語の文字列がすべて文字参照の形式(「&#20253;」のような文字コード)で出力されています。インターネット・エクスプローラ等の XMLの表示に対応したブラウザで表示すると、日本語で表示することが出来ます。

30

9.プログラムのコンパイル

最後に、プログラムのコンパイルです。 ここでも、スキーマ定義のコンパイルと同様の環境設定が必要です。 リスト6 プログラムのコンパイル(太字はコマンド入力)

C:¥java> javac CDAlbum.java これで、クラス定義とプログラムの両方のコンパイルが出来ます。

31

10.コーディングリスト

コーディングリストをリスト7に示します。 リスト7 CDAlbum.java

1: import javax.xml.bind.*; 2: import java.io.*; 3: import java.math.*; 4: import java.text.*; 5: import java.util.*; 6: 7: // スキーマコンパイラが生成したクラスのインポート 8: import educationproject.cdlist.*; 9: 10: // メインプログラム 11: public class CDAlbum { 12: public static void main(String[] args) { 13: String str; 14: FileOutputStream fos = null; 15: // 引数のチェック 16: if (args.length != 1) { 17: // 引数が1個以外の場合はメッセージを出力して終了 18: System.out.println("引数を入力してください。"); 19: System.out.println(" -input : 入力"); 20: System.out.println(" -edit : 編集"); 21: return; 22: } 23: if (args[0].equals("-input")) { 24: // 入力モードの処理 25: try { 26: // JAXBContext オブジェクトの作成 27: JAXBContext jc = 28: JAXBContext.newInstance("educationproject.cdlist"); 29: // ObjectFactory オブジェクトの作成 30: ObjectFactory of = new ObjectFactory(); 31: 32: // CDList 要素の作成 33: CDList cdlist = of.createCDList(); 34: // 複数の子要素のコンテナとなる List オブジェクトの取得 35: List list1 = cdlist.getCD(); 36: // CD 要素の作成 37: CD cd = of.createCD(); 38: // BufferedReader オブジェクトの作成 39: BufferedReader br = 40: new BufferedReader(new InputStreamReader(System.in)); 41: // CD タイトルの入力 42: for ( ; ; ) { 43: System.out.println(">>> CD タイトル"); 44: str = br.readLine(); 45: if (!str.equals("")) break; 46: } 47: // Title 要素の設定

32

48: cd.setTitle(str); 49: // アーティスト名の入力 50: for ( ; ; ) { 51: System.out.println(">>> アーティスト名"); 52: str = br.readLine(); 53: if (!str.equals("")) break; 54: } 55: // Artist 要素の設定 56: cd.setArtist(str); 57: // 発売日の入力 58: for ( ; ; ) { 59: System.out.println(">>> 発売日 (YYYY-MM-DD)"); 60: str = br.readLine(); 61: Calendar cal = Calendar.getInstance(); 62: DateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); 63: try { 64: cal.setTime(formater.parse(str)); 65: // Release 要素の設定 66: cd.setRelease(cal); 67: break; 68: } catch (ParseException e) { 69: System.out.println("発売日の入力に誤りがあります。"); 70: } 71: } 72: // イメージファイル名の入力 73: System.out.println(">>> イメージファイル名"); 74: str = br.readLine(); 75: // Image 要素の設定 76: cd.setImage(str); 77: System.out.println(""); 78: // MusicList 要素の作成 79: MusicList musiclist = of.createMusicList(); 80: // 複数の子要素のコンテナとなる List オブジェクトの取得 81: List list2 = musiclist.getMusic(); 82: for ( ; ; ) { 83: // 曲名の入力 84: System.out.println(">>> 曲名"); 85: str = br.readLine(); 86: // 曲名が入力されなかったら終了 87: if (str.equals("")) break; 88: // Music 要素の作成 89: Music music = of.createMusic(); 90: // Title 属性の設定 91: music.setTitle(str); 92: // 曲時間の入力 93: for ( ; ; ) 94: { 95: System.out.println(">>> 曲時間 (mm:ss)"); 96: str = br.readLine(); 97: Calendar cal = Calendar.getInstance(); 98: DateFormat formater = new SimpleDateFormat("mm:ss"); 99: try { 100: cal.setTime(formater.parse(str)); 101: long sec =

33

102: cal.get(Calendar.MINUTE) * 60 + 103: cal.get(Calendar.SECOND); 104: // Time 属性の設定 105: music.setTime(BigInteger.valueOf(sec)); 106: break; 107: } catch (ParseException e) { 108: System.out.println("曲時間の入力に誤りがあります。"); 109: } 110: } 111: // Music 要素をコンテナに格納 112: list2.add(music); 113: } 114: // MusicList 要素の設定 115: cd.setMusicList(musiclist); 116: // CD 要素をコンテナに格納 117: list1.add(cd); 118: 119: // 作成したデータの妥当性を検証 120: Validator v = jc.createValidator(); 121: boolean valid = v.validateRoot(cdlist); 122: 123: // ファイルへ書き出し 124: Marshaller m = jc.createMarshaller(); 125: m.setProperty(Marshaller.JAXB_ENCODING, "Shift_JIS"); 126: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 127: Boolean.TRUE); 128: fos = new FileOutputStream("CDList.xml"); 129: m.marshal(cdlist, fos); 130: fos.close(); 131: System.out.println("入力データを保存しました。"); 132: return; 133: } catch (JAXBException e) { 134: // JAXB での例外処理(スタックトレースの出力) 135: e.printStackTrace(); 136: } catch (IOException e) { 137: // XMLの書き出しでの例外処理(スタックトレースの出力) 138: e.printStackTrace(); 139: } finally { 140: // ファイルを開いていたら閉じる 141: try { 142: if (fos != null) fos.close(); 143: } catch (IOException e) { 144: e.printStackTrace(); 145: } 146: } 147: System.out.println("エラーが発生しました。"); 148: } 149: else if (args[0].equals("-edit")) { 150: // 編集モードの処理 151: try { 152: // JAXBContext オブジェクトの作成 153: JAXBContext jc = 154: JAXBContext.newInstance("educationproject.cdlist"); 155: // Unmarshaller オブジェクトの取得

34

156: Unmarshaller unmarshaller = jc.createUnmarshaller(); 157: unmarshaller.setValidating(true); 158: 159: // CDList 要素の取得 160: CDList cdlist = 161: (CDList)unmarshaller.unmarshal(new File("CDList.xml")); 162: // CD 要素の取得 163: CD cd = (CD)cdlist.getCD().get(0); 164: // BufferedReader オブジェクトの作成 165: BufferedReader br = 166: new BufferedReader(new InputStreamReader(System.in)); 167: // CD タイトルの編集 168: System.out.println(">>> CD タイトル (" + cd.getTitle() + ")"); 169: str = br.readLine(); 170: // Title 要素の設定 171: if (!str.equals("")) cd.setTitle(str); 172: // アーティスト名の編集 173: System.out.println(">>> アーティスト名 (" + cd.getArtist() + ")"); 174: str = br.readLine(); 175: // Artist 要素の設定 176: if (!str.equals("")) cd.setArtist(str); 177: for ( ; ; ) { 178: // 発売日の編集 179: DateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); 180: System.out.println(">>> 発売日 (" + 181: formater.format(cd.getRelease().getTime()) + ")"); 182: str = br.readLine(); 183: if (str.equals("")) break; 184: Calendar cal = Calendar.getInstance(); 185: try { 186: cal.setTime(formater.parse(str)); 187: // Release 要素の設定 188: cd.setRelease(cal); 189: break; 190: } catch (ParseException e) { 191: System.out.println("発売日の入力に誤りがあります。"); 192: } 193: } 194: // イメージファイル名の編集 195: System.out.println(">>> イメージファイル名 (" + 196: cd.getImage() + ")"); 197: str = br.readLine(); 198: // Image 要素の設定 199: if (!str.equals("")) cd.setImage(str); 200: System.out.println(""); 201: // MusicList 要素から List オブジェクトの取得 202: List list2 = cd.getMusicList().getMusic(); 203: for (int i = 0; i < list2.size(); i++) { 204: // Music 要素の取得 205: Music music = (Music)list2.get(i); 206: System.out.println(">>> 曲名 (" + music.getTitle() + ")"); 207: str = br.readLine(); 208: if (str.equals("")) music.setTitle(str); 209: // 曲時間の編集

35

210: for ( ; ; ) 211: { 212: DecimalFormat df = new DecimalFormat("00"); 213: System.out.println(">>> 曲時間 (" + 214: df.format(music.getTime().longValue() / 60) + ":" + 215: df.format(music.getTime().longValue() % 60) +")"); 216: str = br.readLine(); 217: if (str.equals("")) break; 218: Calendar cal = Calendar.getInstance(); 219: DateFormat formater = new SimpleDateFormat("mm:ss"); 220: try { 221: cal.setTime(formater.parse(str)); 222: long sec = 223: cal.get(Calendar.MINUTE) * 60 + 224: cal.get(Calendar.SECOND); 225: // Time 属性の設定 226: music.setTime(BigInteger.valueOf(sec)); 227: break; 228: } catch (ParseException e) { 229: System.out.println("曲時間の入力に誤りがあります。"); 230: } 231: } 232: } 233: 234: // 作成したデータの妥当性を検証 235: Validator v = jc.createValidator(); 236: boolean valid = v.validateRoot(cdlist); 237: 238: // ファイルへ書き出し 239: Marshaller m = jc.createMarshaller(); 240: m.setProperty(Marshaller.JAXB_ENCODING, "Shift_JIS"); 241: m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, 242: Boolean.TRUE); 243: fos = new FileOutputStream("CDList.xml"); 244: m.marshal(cdlist, fos); 245: fos.close(); 246: System.out.println("入力データを保存しました。"); 247: return; 248: } catch (JAXBException e) { 249: // JAXB での例外処理(スタックトレースの出力) 250: e.printStackTrace(); 251: } catch (IOException e) { 252: // XMLの書き出しでの例外処理(スタックトレースの出力) 253: e.printStackTrace(); 254: } finally { 255: // ファイルを開いていたら閉じる 256: try { 257: if (fos != null) fos.close(); 258: } catch (IOException e) { 259: e.printStackTrace(); 260: } 261: } 262: System.out.println("エラーが発生しました。"); 263: }

36

264: } 265: }