requires=
classes=RSS=Rss,RSS=Rss=Channel,RSS=Rss=SkipDays,RSS=Rss=SkipHours,RSS=Rss=Channel=Image,RSS=Rss=Channel=Cloud,RSS=Rss=Channel=Item,RSS=Rss=Channel=Item=Source,RSS=Rss=Channel=Item=Enclosure,RSS=Rss=Channel=Item=Category,RSS=Rss=Channel=TextInput,RSS=RDF,RSS=ImageModelUtils,RSS=DublinCoreModel,RSS=RDF=Channel,RSS=RDF=Channel=Image,RSS=RDF=Channel=Textinput,RSS=RDF=Channel=Items,RSS=RDF=Channel=ImageFavicon,RSS=RDF=Image,RSS=RDF=Textinput,RSS=RDF=Item,RSS=Rss=Channel=Item=Guid,DublinCoreModel,RSS=SyndicationModel,RSS=TaxonomyTopicModel,RSS=TaxonomyTopicModel=TaxonomyTopic,RSS=TaxonomyTopicsModel,RSS=TaxonomyTopicsModel=TaxonomyTopics,RSS=ImageItemModel,RSS=ImageItemModel=ImageItem,RSS=ImageFaviconModel,RSS=ImageFaviconModel=ImageFavicon,RSS=BaseTrackBackModel,RSS=TrackBackModel10,RSS=TrackBackModel10=TrackBackPing,RSS=TrackBackModel10=TrackBackAbout,RSS=TrackBackModel20,RSS=TrackBackModel20=TrackBackPing,RSS=TrackBackModel20=TrackBackAbout,RSS=ContentModel,RSS=XMLStyleSheet,RSS=XMLStyleSheetMixin,RSS=Maker=ChannelBase=CategoriesBase,RSS=Maker=ItemsBase=ItemBase=CategoriesBase,RSS=Maker=ChannelBase=CategoriesBase=CategoryBase,RSS=Maker=RSS09=Channel=Categories,RSS=Maker=RSS10=Channel=Categories,RSS=Maker=RSS20=Channel=Categories,RSS=Maker=RSS09=Channel=Categories=Category,RSS=Maker=RSS10=Channel=Categories=Category,RSS=Maker=RSS20=Channel=Categories=Category,RSS=Maker=ChannelBase,RSS=Maker=RSS09=Channel,RSS=Maker=RSS10=Channel,RSS=Maker=RSS20=Channel,RSS=Maker,RSS=Maker=RSSBase,RSS=Maker=RSS10,RSS=Maker=RSS20,RSS=Maker=XMLStyleSheets=XMLStyleSheet,RSS=Maker=ChannelBase=SkipDaysBase,RSS=Maker=RSS09=Channel=SkipDays,RSS=Maker=RSS20=Channel=SkipDays,RSS=Maker=ChannelBase=SkipDaysBase=DayBase,RSS=Maker=RSS09=Channel=SkipDays=Day,RSS=Maker=RSS20=Channel=SkipDays=Day,RSS=Maker=ChannelBase=SkipHoursBase,RSS=Maker=RSS09=Channel=SkipHours,RSS=Maker=RSS20=Channel=SkipHours,RSS=Maker=ChannelBase=SkipHoursBase=HourBase,RSS=Maker=RSS09=Channel=SkipHours=Hour,RSS=Maker=RSS20=Channel=SkipHours=Hour,RSS=Maker=ImageBase,RSS=Maker=RSS09=Image,RSS=Maker=RSS10=Image,RSS=Maker=RSS20=Image,RSS=Maker=Base,RSS=Maker=ItemsBase,RSS=Maker=RSS09=Items,RSS=Maker=RSS10=Items,RSS=Maker=RSS20=Items,RSS=Maker=ItemsBase=ItemBase,RSS=Maker=RSS09=Items=Item,RSS=Maker=RSS10=Items=Item,RSS=Maker=RSS20=Items=Item,RSS=Maker=ItemsBase=ItemBase=GuidBase,RSS=Maker=RSS09=Items=Item=Guid,RSS=Maker=RSS20=Items=Item=Guid,RSS=Maker=ItemsBase=ItemBase=EnclosureBase,RSS=Maker=RSS09=Items=Item=Enclosure,RSS=Maker=RSS20=Items=Item=Enclosure,RSS=Maker=ItemsBase=ItemBase=SourceBase,RSS=Maker=RSS09=Items=Item=Source,RSS=Maker=RSS20=Items=Item=Source,RSS=Maker=RSS09=Items=Item=Categories,RSS=Maker=RSS20=Items=Item=Categories,RSS=Maker=TextinputBase,RSS=Maker=RSS09=Textinput,RSS=Maker=RSS10=Textinput,RSS=Maker=RSS20=Textinput,RSS=Parser,RSS=NotWellFormedError,RSS=XMLParserNotFound,RSS=NotValidXMLParser,RSS=NSError,RSS=Element,RSS=RootElementMixin,RSS=Error,RSS=InvalidRSSError,RSS=OverlappedPrefixError,RSS=MissingTagError,RSS=TooMuchTagError,RSS=MissingAttributeError,RSS=UnknownTagError,RSS=NotExpectedTagError,RSS=NotAvailableValueError,RSS=UnknownConversionMethodError,RSS=ConversionError,RSS=NotSetError
methods=RSS=Rss=Channel/i.generator.rss,RSS=Rss=Channel/i.ttl.rss,RSS=Rss=Channel=Item/i.author.rss,RSS=Rss=Channel=Item/i.comments.rss,RSS=Rss=Channel=Item/i.pubDate.rss,RSS=Rss=Channel=Item/i.guid.rss
sublibraries=
is_sublibrary=false
category=FileFormat

RSS を扱うためのライブラリです。

=== 参考

  * RSS 0.91 [[url:http://backend.userland.com/rss091]]
  * RSS 1.0  [[url:http://purl.org/rss/1.0/spec]]  
  * RSS 2.0  [[url:http://www.rssboard.org/rss-specification]]
  * Atom 1.0 [[url:http://www.ietf.org/rfc/rfc4287.txt]]

=== 注意

RSS ParserはRSS 0.9x/1.0/2.0, Atom 1.0 をサポートしていますが，RSS 0.90
はサポートしてません．ごめんなさい．

RSS のモジュールはそれぞれ、
 * Dublin Core モジュール [[url:http://web.resource.org/rss/1.0/modules/dc/]] 
 * Syndication モジュール [[url:http://web.resource.org/rss/1.0/modules/syndication/]]
 * Content モジュール [[url:http://web.resource.org/rss/1.0/modules/content/]]
 * Trackback モジュール [[url:http://madskills.com/public/xml/rss/module/trackback/]]
 * Image モジュール [[url:http://web.resource.org/rss/1.0/modules/image/]]
をサポートしています。
ただし，Content モジュールは content:encoded しかサポートしていません．

=== パース

RSS をパースしたい場合は RSS::Parser クラスを使います。
RSS::Parser.parse は String の RSSを パースします(使用するXMLパー
サによっては File や IO オブジェクトなどでもパース可能です)。
 * RSS 1.0をパースした場合は [[c:RSS::RDF]] オブジェクト
 * RSS 0.9x/2.0をパースした場合は [[c:RSS::Rss]] オブジェクト
 * Atom をパースした場合は [[c:RSS::Atom::Feed]] オブジェクト
をそれぞれ返します。パースした
String が well formed な XML で無い場合は，
例外 [[c:RSS::NotWellFormedError]] が発生します。well formed な
XML だが，RSS 0.9x/1.0/2.0, Atom のいずれでもない場合は，nil が
返ります．

例えば、RSS 1.0 をバリデーション付きでパースするには以下のよ
うにします。ここで、変数 rss_source には RSS 1.0 形式の文
字列が格納されているものとします。

  require 'rss'
  rss = RSS::Parser.parse(rss_source, true)

RSS::Parser.parse の第二引数は省略すると true が指定されたもの
とみなされるので、これは以下のようにも書けます。

  require 'rss'
  rss = RSS::Parser.parse(rss_source)

最初はバリデーション付きでパースして，valid ではない RSS だった
場合はバリデーション無しでパースするには以下のように書きます。

  require 'rss'
  rss = nil
  begin
    rss = RSS::Parser.parse(rss_source)
  rescue RSS::InvalidRSSError
    rss = RSS::Parser.parse(rss_source, false)
  end

これは rss_source が RSS 0.9x/1.0/2.0 のどれか分からない時
にも有効です。RSS 1.0としてバリデー
ション付きでパースし、バリデーションに失敗すると RSS 0.9x/(壊
れた)1.0/2.0 のいずれかとしてパースします。

==== 知らない要素の扱い

パーサはデフォルトでは知らない要素(仕様書に規定されていない
要素)を無視します。もし、知らない要素に遭遇した時に例外を発
生させたければ，RSS::Parser.parse の第三引数に false を指定して
ください。こうすると、パース中に知らない要素に遭遇した時に
[[c:RSS::UnknownTagError]] 例外が発生します。RSS::UnknownTagError
クラスは [[c:RSS::InvalidError]] クラスのサブクラスです。

以下のようにすると，より厳密にパースできます。

  RSS::Parser.parse(rss_source, true, false)

=== パースされたフィード

フィードをパースすると  [[c:RSS::RDF]], [[c:RSS::RDF::Channel]],
[[c:RSS::Rss]], [[c:RSS::Atom::Feed]] 等のオブジェクトになります。
各オブジェクトで子要素オブジェクトにアクセスするために，要素名と
同じ名前のアクセサがあります。

==== リーダ(reader)

rdf:RDF 要素の子要素である channel 要素を参照するには，以下のよう
にします。

  rss = RSS::Parser.parse(rss_source)
  rss.channel # => /rdf:RDF/channel要素; RSS::RDF::Channel

もし、要素が子要素も属性も持たない場合は String が返ってきます。
その要素が省略可能ならばnilが返って来るかもしれません。これ
は要素が子要素または属性を持つ場合も同様です。

  rss = RSS::Parser.parse(rss_source)
  rss.channel.description # => /rdf:RDF/channel/text(); String

属性にアクセスする時も同様です。channel要素のrdf:about属性に
アクセスするには以下のようにします。属性の値はStringかnilで
す。

  rss = RSS::Parser.parse(rss_source)
  rss.channel.about # => /rdf:RDF/channel/@about属性; String または nil

同名の複数の子要素があるかもしれないときも同様です。ただし、
リーダに引数を指定しないと最初の子要素が返ってきます。例えば、
rdf:RDF要素の最初のitem要素にアクセスするには以下のようにし
ます。

  rss = RSS::Parser.parse(rss_source)
  rss.item # => /rdf:RDF/item[1]要素; RSS::RDF::Item

3番目のitem要素にアクセスするには以下のようにします。省略さ
れなかったリーダの引数はArray#[]の引数と同じように扱われます。

  rss = RSS::Parser.parse(rss_source)
  rss.item(2) # => /rdf:RDF/item[3]要素; RSS::RDF::Item

子要素すべてを取得したいときは要素名の複数形がリーダとなりま
す。すべてのitem要素を取得するには以下のようにします。

  rss = RSS::Parser.parse(rss_source)
  rss.items # => /rdf:RDF/item要素の配列; [RSS::RDF::Item, ...]

==== ライタ(writer)

rdf:RDF要素の子要素であるchannel要素を設定するには以下のよう
にします。RSS::RDF::Channel.newの第一引数にはrdf:about属性の
値を指定することもできます。

  rss = RSS::Parser.parse(rss_source)
  rss.channel = RSS::RDF::Channel.new(rdf_about_value)

属性値を設定する場合も同様です。

  rss = RSS::Parser.parse(rss_source)
  rss.channel.about = "http://cozmixng.www.cozmixng.org/"

同名の複数の子要素が存在する場合は少し異なります．要素名の複
数形でのメソッドで要素の配列を取得して，その配列に対して
Array#<<やArray#[]=などを用いて要素を設定します．

  rss = RSS::Parser.parse(rss_source)
  item = RSS::RDF::Item.new(rdf_about_value)
  rss.items << item
  rss.items.last == item # => true

注意: item=/set_itemなどはRubyっぽくないので使わないでくださ
い．

=== 出力

RSS Parserといっているので誤解されがちですが，RSS/Atomを出力する
こともできます．

==== 基本

to_sするとRSSまたはAtom形式の文字列を返します．

RSS/Atomを出力する流れは以下のようになります．

  * RSS/Atomオブジェクト（RSS::RDFとかRSS::Rssクラスとか
    RSS::Atom::Feedのオブジェクト）を作成する

  * 出力エンコーディングを指定する(省略可)

  * RSSオブジェクトのto_sメソッドを呼ぶ

==== xml-stylesheet

xml-stylesheetも出力することができます．

RSSのルート要素（RSS::RDFまたはRSS::Rss）オブジェ
クトおよびAtomのルート要素（RSS::Atom::Feedまたは
RSS::Atom::Entry）オブジェクトはxml_stylesheetsという
名前の配列を持っています．この配列にRSS::XMLStyleSheet
オブジェクトを挿入することでRSS/Atomにxml-stylesheetを
関連づけることができます．

  rss.xml_stylesheets << RSS::XMLStyleSheet.new(...)

RSS::XMLStyleSheet.newには以下のようなHashまたは
連想配列を渡します．作成されるRSS::XMLStyleSheetオブジェ
クトは与えられた引数によって初期化されます．

Hash:

  {
    :href => "...",
    :type => "...",
    :title => "...",
    :media => "...",
    :charset => "...",
    :alternate => "...",
  }

連想配列:

  [
    [:href, "..."],
    [:type, "..."],
    [:title, "..."],
    [:media, "..."],
    [:charset, "..."],
    [:alternate, "..."],
  ]

全てのキーは省略可能です．

例えば，xml-stylesheetとしてsample.xslを指定する場合は以下の
ようにします．

  rss.xml_stylesheets << RSS::XMLStyleSheet.new({:href => "sample.xsl"})

本当は{:type => "text/xsl"}も指定しないといけないとこ
ろですが，拡張子が.xslまたは，.cssの場合は適当に推測してくれ
るので省略可能です．

==== RSS/Atomオブジェクトを作る

既存のRSS/Atomをパースせずに，一から新しくRSS/Atomを作成するには
RSS Makerが便利です．


以下のように使います．

  require "rss"

  rss = RSS::Maker.make("バージョン") do |maker|
    maker.XXX = YYY
    ...
  end

===== シンプルなRSS

例えば，

  * http://example.com/にある
  * Example Siteという説明文を持つ
  * Exampleというサイトを
  * http://example.com/index.rdfという名前のRSS 1.0

を生成するには以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"
  end

もし，

  * http://example.com/article.htmlにある
  * Sample Articleというタイトルの

エントリを含めたければ以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    item = maker.items.new_item
    item.link = "http://example.com/article.html"
    item.title = "Sample Article"
  end

===== 更新時刻を追加

もし，先のエントリが

  * 2004/11/1 10:10

のものならこうします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end
  end

サンプル中の

  item.date = ...

は

  item.dc_date = ...

でも構いません．#dc_date=は#date=の単なる別名で
す．

===== さらにエントリを追加

さらに，

  * http://example.com/article2.htmlにある
  * Sample Article2という
  * 2004/11/2 10:10に作成された

エントリを持つなら以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end
  end

===== エントリを並び替える

もし，更新日が新しい順に並び替えたければ

  maker.items.do_sort = true

を追加し，以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.do_sort = true

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end
  end

===== ロゴの指定

もし，サイトに

  * Example Siteという名前の
  * http://example.com/logo.pngというロゴ

がある場合は以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.do_sort = true

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end

    maker.image.title = "Example Site"
    maker.image.url = "http://example.com/logo.png"
  end

===== 検索ページの指定

もし，

  * http://example.com/search.cgiに
  * keywordというパラメタ名で検索できる
  * Search Example Siteという名前で
  * Search Example Site's all textという説明付きの

検索用ページがあったら以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.do_sort = true

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end

    maker.image.title = "Example Site"
    maker.image.url = "http://example.com/logo.png"

    maker.textinput.title = "Search Example Site"
    maker.textinput.description = "Search Example Site's all text"
    maker.textinput.name = "keyword"
    maker.textinput.link = "http://example.com/search.cgi"
  end

===== XMLスタイルシートの指定

もし，

  * http://example.com/index.xslにある

xml-stylesheetを追加したい場合は以下のようにします．

  require "rss"

  rss = RSS::Maker.make("1.0") do |maker|
    xss = maker.xml_stylesheets.new_xml_stylesheet
    xss.href = "http://example.com/index.xsl"

    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.do_sort = true

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end

    maker.image.title = "Example Site"
    maker.image.url = "http://example.com/logo.png"

    maker.textinput.title = "Search Example Site"
    maker.textinput.description = "Search Example Site's all text"
    maker.textinput.name = "keyword"
    maker.textinput.link = "http://example.com/search.cgi"
  end

===== RSS 2.0の生成

もし，RSS 2.0を生成したい場合は以下のように，
RSS::Maker.makeの第一引数を変更します．

  require "rss"

  rss = RSS::Maker.make("2.0") do |maker|
    xss = maker.xml_stylesheets.new_xml_stylesheet
    xss.href = "http://example.com/index.xsl"

    maker.channel.about = "http://example.com/index.rdf"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.items.do_sort = true

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end

    maker.image.title = "Example Site"
    maker.image.url = "http://example.com/logo.png"

    maker.textinput.title = "Search Example Site"
    maker.textinput.description = "Search Example Site's all text"
    maker.textinput.name = "keyword"
    maker.textinput.link = "http://example.com/search.cgi"
  end

===== RSS 0.91の生成

もし，RSS 0.91を生成したい場合は，RSS 2.0の場合と同様に
RSS::Maker.make の第一引数を"0.91"に変更します．

ただし、RSS 0.91では言語指定が必須なので、言語を指定する必要
があります。ここでは日本語であると指定します。

  rss = RSS::Maker.make("0.91") do |maker|
    maker.channel.language = "ja"
    ...
  end

RSS 1.0など、/rdf:RDF/channel/language要素がないフィードの場
合でも、単に無視したりdc:languageとして扱ったりと適切に処理し
ます。そのため、以下のように「バージョンが"0.91"のとき
だけ言語を指定する」というように書く必要はありません。
フィードのバージョンに関わらず言語を指定してください。

  rss = RSS::Maker.make("0.91") do |maker|
    maker.channel.language = "ja" if maker.feed_version == "0.91"
    ...
  end

===== Atom 1.0の生成

もし，Atom 1.0を生成したい場合は，RSS 0.91や2.0の場合と同様に
RSS::Maker.makeの第一引数を"atom"に変更します．

  rss = RSS::Maker.make("atom") do |maker|
    ...
  end

ただし、これだけでは十分ではありません。これは、Atom 1.0では
RSS 1.0/2.0/0.91では必須ではなかった以下の情報が必要となるか
らです。

  * このAtom 1.0の作者
  * このAtom 1.0の更新日

よって、これまでのスクリプトをAtom 1.0を出力するようにするた
めには以下のように変更する必要があります。

  * RSS::Maker.makeの第一引数を"atom"に変更
  * maker.channel.authorを設定
  * maker.channel.dateを設定

もし、

  * 作者がBobで
  * たった今、作成された

Atom 1.0なら以下のようになります。

  require "rss"

  atom = RSS::Maker.make("atom") do |maker|
    xss = maker.xml_stylesheets.new_xml_stylesheet
    xss.href = "http://example.com/index.xsl"

    maker.channel.about = "http://example.com/atom.xml"
    maker.channel.title = "Example"
    maker.channel.description = "Example Site"
    maker.channel.link = "http://example.com/"

    maker.channel.author = "Bob"
    maker.channel.date = Time.now

    maker.items.do_sort = true

    maker.items.new_item do |item|
      item.link = "http://example.com/article.html"
      item.title = "Sample Article"
      item.date = Time.parse("2004/11/1 10:10")
    end

    maker.items.new_item do |item|
      item.link = "http://example.com/article2.html"
      item.title = "Sample Article2"
      item.date = Time.parse("2004/11/2 10:10")
    end

    maker.image.title = "Example Site"
    maker.image.url = "http://example.com/logo.png"

    maker.textinput.title = "Search Example Site"
    maker.textinput.description = "Search Example Site's all text"
    maker.textinput.name = "keyword"
    maker.textinput.link = "http://example.com/search.cgi"
  end

Atom 1.0用の情報を加えたこのスクリプトを最初のRSS 1.0を出
力するスクリプトに戻す場合は、RSS::Maker.makeの第一引
数を"1.0"に変えるだけです。Atom 1.0用に追加した情報を
削除する必要はありません。それらは単に無視されます。

==== RSS/Atomオブジェクトを変換する

フィードの種類がRSS 1.0/2.0でもAtomでもパースするためのAPIは
以下のように共通です。

  feed = RSS::Parser.parse(feed_xml)

しかし、返ってくるオブジェクトはRSS 1.0オブジェクト
（RSS::RDF）かもしれませんし、Atomオブジェクト
（RSS::Atom::Feed）かもしれません。このため、パースした結果
を使う場合はフィードの種類を意識しなくてはならず、
使いづらくなります。

RSS Parserが提供する解決方法はユーザに好みのフィードの種類を
選んでもらうというものです。例えば、以下のようにしてRSS 1.0
をRSS 2.0に変換することができます。

  require 'rss'
  rss10 = RSS::Parser.parse(rss10_xml)
  rss20 = rss10.to_feed("rss2.0")

種類がわからない複数のフィードを扱う場合は以下のようにし、す
べてのフィードをRSS 2.0のように扱うことができます。

  feeds.each do |xml|
    rss20 = RSS::Parser.parse(xml).to_feed("rss2.0")
    ...
  end

また、to_feedは以下のように書くことも出来ます。

  feed.to_rss("1.0") # == feed.to_feed("rss1.0")
  feed.to_rss("2.0") # == feed.to_feed("rss2.0")
  feed.to_atom("1.0") # == feed.to_feed("atom1.0")

形式を変換したときに問題になるのは、変換元のオブジェクトが変
換後の形式に必須の情報を持っていない場合です。この場合は変換
に失敗します（RSS::Errorのサブクラスの例外が発生します）。そ
のため、適宜、必要な情報を補う必要があります。たとえば、RSS
1.0では各item要素にタイトルが必須ですが、RSS 2.0では省略可能
です。そのような場合に対応するために、以下のようにブロックを
使用することが出来ます。

  rss10 = feed.to_rss("1.0") do |maker|
    maker.items.each do |item|
      item.title.content ||= "No title"
    end
  end

to_feedのブロック内で出来ることを理解するためには、to_feedが
どのように動作するかを理解するとよいです。パース結果のオブジェ
クトはフィードの種類に関わらずsetup_makerというメソッドを持っ
ています。これは、自分が持っている情報をRSS Makerに与えるメソッ
ドです。to_feedはRSS::Maker.makeで作ったRSS Makerに対して
setup_makerを行い、他の形式に変換しようとします。ブロックには
setup_makerを行った後のRSS Makerが渡されます。つまり、
to_feedのブロック内で出来ることはRSS Makerに対して出来ること
と同じです。

==== フィードの形式を変換する

上記の方法でパース済みのオブジェクトを変換できるので、フィー
ドを異なる形式のXMLへ変換することは簡単です。

  feed = RSS::Parser.parse(feed_xml)
  new_feed_xml = feed.to_feed("atom1.0").to_s

これを行うための便利なメソッドto_xmlがあります。to_xmlを使う
と以下のように書き直すことができます。

  feed = RSS::Parser.parse(feed_xml)
  new_feed_xml = feed.to_xml("atom1.0")

。。。あまり変わりませんね。to_feedを用いた場合と同じように
ブロックを指定してRSS Makerを操作することも出来ます。ますま
す変わりませんね。

to_feed().to_sではなく、to_xmlを使うことには一長一短がありま
す。to_xmlは変換元のフィードの種類と変換後のフィードの種類が
同じ場合は単にto_sを呼び出すだけです。これにより、同じ形式に
変換する場合の速度があがります（RSS Makerを作って変換、という
ことを省略するので当然です）。しかし、ブロックを指定して変換
後の結果を調整することができません。例えば、以下のようにRSS
1.0からRSS 2.0に変換する場合はブロックが呼ばれます。

  rss10.to_xml("rss2.0") do |maker|
    # makerを操作できる
  end

しかし、以下のようにRSS 1.0からRSS 1.0に変換しようとした場合
はブロックは呼び出されません。

  rss10.to_xml("rss1.0") do |maker|
    # ブロックが呼び出されないのでmakerを操作できない。
  end

このAPIに関しては、どうしたらよいのかまだ悩んでいます。もし、
なにかアイディアがあれば教えてください。

=== サンプル

RSS Parser のサンプルスクリプトをいくつか紹介します．これらの
スクリプトは sample/ 以下に入っています．

==== サンプル1 - 項目一覧

それでは、複数のフィードをパースしてitem要素を表示するスクリプト
を書いてみましょう。

まず、RSS 0.9x/1.0/2.0, Atom 1.0をパースできるように以下のようにrequireします。

  require 'rss'

パースするフィードはファイルに保存されていて引数で与えられるものとします。

  ARGV.each do |fname|
    feed = nil
    begin
      feed = RSS::Parser.parse(File.read(fname), false)
    rescue RSS::Error
    end

    if feed.nil?
      puts "#{fname}はRSS 0.9x/1.0/2.0, Atom 1.0のいずれでもありません。"
    else
      print_items(feed)
    end
  end

あとはprint_itemsというメソッドを定義するだけです。

RSS::RDF/RSS::Rss/RSS::Atom::Feed/RSS::Atom::Entryには便利の
ためにitemsというメソッドとimageというメソッドが定義されています。

itemsはそれぞれ以下を返します。

  * RSS::RDF: 全ての/rdf:RDF/item要素の配列
  * RSS::Rss: 全ての/rss/channel/item要素の配列
  * RSS::Atom::Feed: 全ての/atom:feed/atom:entry要素の配列
  * RSS::Atom::Entry: /atom:entry要素のみが含まれる配列

imageはそれぞれ以下を返します。

  * RSS::RDF: /rdf:RDF/image要素
  * RSS::Rss: /rss/channel/image要素

ここでは、itemsを使って各項目を表示します。

  def print_items(feed)
    feed.items.each do |item|
      puts "#{item.title} : #{item.description}"
    end
  end

これは、RSSフィードに対してはうまく動きますが、Atomフィードに
対してはうまく動きません。それはAtomフィードにはdescription要
素がないからです。そこで、AtomフィードもRSSフィードに変えて
扱うことにします。

  def print_items(feed)
    convert_to_rss10(feed).items.each do |item|
      puts "#{item.title} : #{item.description}"
    end
  end

convert_to_rss10は以下のようになります。

  def convert_to_rss10(feed)
    feed.to_rss("1.0") do |maker|
      maker.channel.about ||= maker.channel.link
      maker.channel.description.content ||= "No description"
      maker.items.each do |item|
        item.title.content ||= "No title"
        item.link ||= "UNKNOWN"
      end
    end
  end

未設定の可能性がある要素にデフォルト値を設定しています。

出力する文字コードを変更するにはoutput_encoding=が使えます。
もし、変換できないエンコーディングを指定された場合は
RSS::UnknownConversionMethodError例外が発生します。

先程のprint_itemsをEUC-JPで出力するように書き換えてみましょう。

  def print_items(feed)
    rss10 = convert_to_rss10(feed)
    begin
      rss10.output_encoding = "EUC-JP"
    rescue RSS::UnknownConversionMethodError
    end
    rss10.items.each do |item|
      puts "#{item.title} : #{item.description}"
    end
  end

==== サンプル2 - 更新順表示

次はDublin Coreモジュールのdate属性を使って更新順にitemを表
示してみましょう。

最初に現れたDublin Coreモジュールの要素にアクセスするには
「dc_要素名」というアクセサが用意されています。全ての要素の
配列にアクセスするには「dc_要素の複数形」（dc_rightsは
dc_rights_listになります）とします．

複数形でアクセスした場合は「要素の内容を表す文字列」ではなく，
「要素を表すオブジェクト」の配列が返ります．「要素を表すオブ
ジェクト」から「要素の内容を表す文字列」を取得するには
contentメソッドやその別名であるvalueメソッドを利
用します．「要素の内容を表す文字列」を設定するには
content=メソッドやその別名であるvalue=メソッドを
利用します．

  rss.channel.dc_title  # => 「要素の内容を表す文字列」
                        # （"My site"など）

  rss.channel.dc_titles # => 「要素を表すオブジェクト」の配列
                        # （[DublinCoreTitleオブジェクト, ...]）

  rss.channel.dc_titles.collect {|title| title.value}
                        # => 「要素の内容を表す文字列」の配列
                        # （["My site", ...]など）

  rss.channel.dc_titles.first.value == rss.channel.dc_title
                        # => true
  # 厳密にはこう
  first_title = rss.channel.dc_titles.first
  first_title = first_title.value if first_title
  first_title == rss.channel.dc_title
                        # => true

ちなみにSyndicationモジュールの要素にアクセスするには「sy_要
素名」というアクセサが，Contentモジュールの要素にアクセスす
るには「content_要素名」というアクセサが用意されています。

サンプル1と同じようにパースするRSSはファイルに保存されていて
引数で与えられるものとします。

  require 'rss'
  items = []
  ARGV.each do |fname|
    rss_source = nil
    File.open(fname) do |f|
      rss_source = f.read
    end

    rss = nil
    begin
      rss = RSS::Parser.parse(rss_source, true)
    rescue RSS::Error
    end

    if rss.nil?
      puts "#{fname}はRSS 1.0ではありません。"
    else
      begin
        rss.output_encoding = "euc-jp"
      rescue RSS::UnknownConversionMethodError
      end
      rss.items.each do |item|
        items << item if item.dc_date
      end
    end
  end
  print_items(items)

あとはprint_itemsというメソッドを定義するだけです。

Item#dc_dateはTimeオブジェクトかnilを返します。引数の
itemsにはdc_dateがnilではないものしか含まれていないは
ずなので以下のようにソートできます。

  def print_items(items)
    items.sort do |x, y|
      y.dc_date <=> x.dc_date
    end.each do |item|
      puts "#{item.dc_date.localtime.iso8601} : #{item.title} : #{item.description}"
    end
  end
