Ruby RSS::MakerでCDATAを扱えるようにしてみる  [ruby]  [sample_code]  [tips]

RubyのRSS::MakerでRSS1.0生成すると、content:encodedが自動的にhtml_escapeされてしまい、CDATAとして埋め込んでくれないので、モンキーパッチングしてみた。

rss_cdata.rb

require 'rss'

module RSS
  module BaseModel
    def install_cdata_element(tag_name, uri, occurs, name=nil, type=nil, disp_name=nil)
      name ||= tag_name
      disp_name ||= name
      self::ELEMENTS << name
      add_need_initialize_variable(name)
      install_model(tag_name, uri, occurs, name)

      def_corresponded_attr_writer name, type, disp_name
      convert_attr_reader name
      install_element(name) do |n, elem_name|
        <<-EOC
        if @#{n}
          rv = "\#{indent}<#{elem_name}>"
          value = "<![CDATA[" + eval("@#{n}") + "]]>"
          if need_convert
            rv << convert(value)
          else
            rv << value
          end
          rv << "</#{elem_name}>"
          rv
        else
          ''
        end
EOC
      end
    end
  end 
  
  module ContentModel
    def self.append_features(klass)
      super 
      
      klass.install_must_call_validator(CONTENT_PREFIX, CONTENT_URI)
      %w(encoded).each do |name|
        klass.install_cdata_element(name, CONTENT_URI, "?", "#{CONTENT_PREFIX}_#{name}")
      end
    end
  end 
  
  class RDF
    class Item; include ContentModel; end
  end
end

試してみる

require 'rss'
require './rss_cdata'
 
rss = RSS::Maker.make("1.0") do | maker |
  maker.channel.about = "http://hoge.fuga/index.rdf"
  maker.channel.title = "harahoro"
  maker.channel.description = "hirehare"
  maker.channel.link = "http://hoge.fuga/"
  item = maker.items.new_item
  item.link = "http://hoge.fuga/piyo.html"
  item.title = "aheaheuhiha"
  item.content_encoded = "<p>aheuhihaaa</p>"
  item.dc_date = Time.now()
end 
puts rss.to_s

結果

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:image="http://web.resource.org/rss/1.0/modules/image/"
  xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/"
  xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
  xmlns="http://purl.org/rss/1.0/">
  <channel rdf:about="http://hoge.fuga/index.rdf">
    <title>harahoro</title>
    <link>http://hoge.fuga/</link>
    <description>hirehare</description>
    <items>
      <rdf:Seq>
        <rdf:li resource="http://hoge.fuga/piyo.html"/>
      </rdf:Seq>
    </items>
    <taxo:topics>
      <rdf:Bag/>
    </taxo:topics>
  </channel>
  <item rdf:about="http://hoge.fuga/piyo.html">
    <title>aheaheuhiha</title>
    <link>http://hoge.fuga/piyo.html</link>
    <content:encoded><![CDATA[<p>aheuhihaaa</p>]]></content:encoded>
    <dc:date>2009-12-02T13:14:24+09:00</dc:date>
    <taxo:topics>
      <rdf:Bag/>
    </taxo:topics>
    <content:encoded><![CDATA[<p>aheuhihaaa</p>]]></content:encoded>
  </item>
</rdf:RDF>

どうよ。