MAP | SASAX-RSS ドキュメント > 実装メモ |
本ドキュメントの目的は、 SASAX-RSS 実装の詳細を説明することにあります。
このドキュメントは、 SASAX フレームワーク上で固有の XML 文書パーサを記述する際の、 一助になるでしょう。
注意: 本ドキュメントで提示するソースコードは、 配布物との厳密な一致よりも、 説明の簡便さを優先しました。
チュートリアルでの記述と配布物の違いに、 混乱しないことを願います。
本チュートリアルでは、 クラスは全てクラス名のみで表記されています。 完全な名称は以下の通りです。
表記 | 完全名 |
---|---|
Attributes | org.xml.sax.Attributes |
SAXException | org.xml.sax.SAXException |
これらのクラスの詳細に関しては、 ドキュメント配布版ないし WEB 版の JavaDoc を参照してください。
表記 | 完全名 |
---|---|
AbstractElement | jp.ne.dti.lares.foozy.sasax.AbstractElement |
CompositeElement | jp.ne.dti.lares.foozy.sasax.CompositeElement |
DateTimeElement | jp.ne.dti.lares.foozy.sasax.DateTimeElement |
Element | jp.ne.dti.lares.foozy.sasax.Element |
ElementDrivenHandler | jp.ne.dti.lares.foozy.sasax.ElementDrivenHandler |
Notification | jp.ne.dti.lares.foozy.sasax.Notification |
ParseContext | jp.ne.dti.lares.foozy.sasax.ParseContext |
表記 | 完全名 |
---|---|
ChannelElement | jp.ne.dti.lares.foozy.sasax.rss.ChannelElement |
ItemElement | jp.ne.dti.lares.foozy.sasax.rss.ItemElement |
RSSRootElement | jp.ne.dti.lares.foozy.sasax.rss.RSSRootElement |
表記 | 完全名 |
---|---|
Channel | jp.ne.dti.lares.foozy.sasax.rss.Channel |
ChannelNotification | jp.ne.dti.lares.foozy.sasax.rss.ChannelNotification |
Item | jp.ne.dti.lares.foozy.sasax.rss.Item |
ItemNotification | jp.ne.dti.lares.foozy.sasax.rss.ItemNotification |
SASAX のチュートリアルを既読で RSS 仕様を理解しているのであれば、 SASAX-RSS のパーサ部を読んで理解するのは十分容易です。
SASAX チュートリアルで記述されていない幾つかの事柄のうちの一つに、
"ignore"/"ordered" 引数を持つ
CompositeElement
コンストラクタのことがあります。
このコンストラクタは SASAX 1.2 から導入され、 以下の意味を持ちます。
この引数は、 文書中の要素の出現順が登録順と一致している必要があるか否かを表します。 RSS 仕様書によれば、 要素順は制限されていません。
SASAX-RSS パーサは、 指定された XML 文書が RSS 文書として適切か否かの検証しかしません。
RSS 文書から情報 (例: "channel" の詳細, "item" の一覧等々)を取得するためには、 何らかのことをする必要があり、 ほとんど全ての場合において「何らかのこと」とは情報コンテナの設定です。
情報コンテナの設定は XML 文書からの(情報コンテナ) オブジェクトのデシリアライズの一種と言える物で、 コンテナ定義固有のものです。 そのため、SASAX-RSS の GUI 部の持っているデシリアライズ実装は、 SASAX-RSS パーサとは分離されています。
SASAX を利用する際の解析結果取得には幾つかの方法があります。
notifyDetermined()
メソッドのオーバライド:AbstractElement
派生クラスにおいてこの方法を使用する事で、
値確定後に即座に解析結果を取得することが出来ますが、
Element
実装クラスと結果処理ロジックの双方の再利用性が低下します。
Notification
として開始/終了イベントを受け取る:Notification
実装とすることで、
XML 文書解析ロジックと、
個々のアプリケーション固有のデシリアライズロジックを、
それぞれ分離することが出来ます。そのため、SASAX-RSS では最後の手法を選択しました。
例えば、
"channel" RSS 要素のデシリアライズコードは以下のようになります。
これは Notification
実装クラスである
ChannelNotification
のものです。
以下の例では
"channel_
" は Channel
型のメンバフィールドです。
Channel
は RSS "channel" 情報を格納するためのコンテナです。
public void elementStarted(Element element, ParseContext context, Attributes attributes) throws SAXException // { // "rdf:about" 属性の取得 String about = attributes.getValue("http://purl.org/rss/1.0/", "about"); channel_.setValue("rdf:about", // 値の名前 about); }
ハイライト部分は XML 文書由来の情報を保持していることを表しています。
public void elementEnded(Element element, ParseContext context) throws SAXException // { ChannelElement channel = (ChannelElement)element; // "rss:title" 値の取得 channel_.setValue("title", channel.title.getString(true)); // "rss:link" 値の取得 channel_.setValue("link", channel.link.getString(true)); // "rss:description" 値の取得 channel_.setValue("description", channel.description.getString(true)); }
要素属性値を必要とするデシリアライズ処理は
elementStarted()
に、
下位要素の確定が必要とされる他のデシリアライズ処理は
elementEnded()
に記述されます。
難しくないですよね?
解析時には、
デシリアライズを行うための Notification
を、
対応する要素に対して以下のように登録する必要があります。
// 情報コンテナの生成 Channel channel = new Channel(); // RSS 文書解析用Element
の生成 RSSRootElement root = new RSSRootElement(null); // "channel" 要素へのNotifiation
の登録 root.channel.addNotification(new ChannelNotification(channel)); : ElementDrivenHandler handler = new ElementDrivenHandler(root); handler.parse(reader); // RSS XML 文書の解析 // この時点で XML 文書からChannel
がデシリアライズされる
本節では、 RSS "item" 配下へ "Dublin Core" の "date" を追加するための実装を示すことで、 拡張要素の追加とそこからの値取得の方法に関して説明します。
SASAX-RSS GUI ソースファイルでは、
"Dublin Core" の "date" 向け固有の実装部分を
">>>> DC:DATE
"
および "<<<< DC:DATE
" で囲んであります。
このような箇所は4箇所しかありません。 そのうちの一つは共有のための文字列シンボル定義であり、 もう一つは表示のためのものです。 それ以外の二つが純粋にデシリアライズのためのコードで、 "要素の登録" と "要素からのデシリアライズ" です。
"Dublin Core" の "date" には
DateTimeElement
が利用可能で、
要素登録コードは以下のようになります。
LooseDateTimeElement dcDate =
new LooseDateTimeElement(root.item,
"http://purl.org/dc/elements/1.1/",
"date",
null // GMT タイムゾーンの意
);
// dcDate 要素を "item" 配下に非必須要素として登録
root.item.addOptionalItem("dc:date", dcDate);
"item" 要素のための
ItemNotification
におけるデシリアライズコードは、
以下のようになります。
public void elementEnded(Element element,
ParseContext context)
throws SAXException //
{
ItemElement item = (ItemElement)element;
:
LooseDateTimeElement dcDate =
(LooseDateTimeElement)(item.getComponent("dc:date"));
item_.setValue("dc:date", dcDate.getDate(false));
}
上記例での "item_
" は、
Item
型のメンバフィールドです。
Item
は RSS "item" の情報を格納するコンテナです。
MAP | SASAX-RSS ドキュメント > 実装メモ |