Ruby の REXML と RSS Maker で Amazon で売れてるオライリー本のフィードを簡単に作る

使用したライブラリ open-uri rexml/document rss/maker RSS Parser ※ We retire raa.ruby-lang.org という Amazon Web Service を簡単に使えるライブラリも存在するが、単にリストを取得するだけなので今回は見送った。 コード RSS 2.0 で出力する。RSS::Maker.make(version) で引数にバージョンを入れて指定する。 Description にイメージと著者、出版日、価格を入れている。Author は複数タグあるため、カンマで結合。 同じようなものを仕事で Java で作ったことがあったが、Ruby などの Light Weight 言語の手軽さを知ってしまうと戻れない。 結果: http://feed.tilfin.net/amazon/oreilly-bestseller.xml 下記のコードでは、ファイル書き出しをコメントアウトして、CGIとしての動作を有効にさせている。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #!/usr/bin/env ruby # # Amazon O'Relly Sales Ranking # Rss feed # ################################# require 'open-uri' require 'rexml/document' require 'rss/maker' param = { 'Service' => 'AWSECommerceService', 'AWSAccessKeyId' => '☆アクセスキーID☆', 'AssociateTag' => '☆アソシエイトID☆', 'Operation' => 'ItemSearch', 'SearchIndex' => 'Books', 'ResponseGroup' => 'Medium', 'Sort' => 'salesrank', 'Publisher' => 'オライリー' } params = param.map do |key, value| "#{URI.encode(key)}=#{URI.encode(value)}" end.join("&") doc = nil open('http://webservices.amazon.co.jp/onca/xml?' \+ params) { |resp| doc = REXML::Document.new(resp) } rss = RSS::Maker.make("2.0") do |maker| maker.channel.title = "O'Reilly ベストセラー (Amazon)" maker.channel.description = "O'Reilly の Amazon.co.jp のセールストップ 10 を紹介" maker.channel.link = "http://feed.tilfin.net/amazon/orelly-bestseller.xml" number = 0 doc.elements.each("/ItemSearchResponse/Items/Item") do |item| itmat = item.elements\["ItemAttributes"\] number += 1 entry = maker.items.new_item entry.title = number.to_s + '. ' \+ itmat.elements\["Title"\].text entry.link = item.elements\["DetailPageURL"\].text desc = nil item.elements.each("MediumImage") { |img| desc = <<EOS <img src="#{img.elements\["URL"\].text}" width="#{img.elements\["Width"\].text}" height="#{img.elements\["Height"\].text}"><br> EOS } desc += itmat.elements.each("Author") { |a| a.text }.join(", ") \+ " (著)" desc += "<br>発売日:" \+ itmat.elements\["PublicationDate"\].text.gsub(/-/, '/') desc += "<br>" \+ itmat.elements\["ListPrice/FormattedPrice"\].text entry.description = desc entry.date = Time.now end end print "Content-Type:application/rss+xml\\r\\n\\r\\n" print rss #open("oreilly-bestseller.xml", "w") { |out| \# out.print rss #} #``` ※IE7だと application/rss だけではフィードだと認識されなかった。

2008年1月3日 · Toshimitsu Takahashi

REXML

Ruby の XML ライブラリ REXML を試す。(REXML - Home) Rubyクックブック ―エキスパートのための応用レシピ集 を買ったが、REXML については書かれていない。オリジナルの Ruby Cookbook (Cookbooks (O’Reilly)) には REXML が一章使われて説明されているらしい。 #!/usr/bin/env ruby require “rexml/document” include REXML xml = «EOS メモ 日本語 ENGLISH EOS doc = Document.new xml doc.elements.each("/records/record") do |el| el.elements.each("item") do |item| puts item item.elements.each("title") { |e| puts e.text } item.elements.each("title\[1\]") { |e| puts e } item.elements.each("title\[2\]") { |e| puts e.text } item.elements.each("title\[@lang='ja'\]") { |e| puts e.text } item.elements.each("title\[@lang='en'\]") { |e| puts e } end end puts doc.root.elements\["memo"\].text 実行結果 ...

2007年12月31日 · Toshimitsu Takahashi

Excel の XML スプレッドシート形式を XSLT で一般的な XML に整形する

1行目を列名とする。 book → シート名 → row → 列名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <?xml version="1.0" encoding="Shift_JIS"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="Workbook" /> </xsl:template> <!-- ブックの書き出し --> <xsl:template match="Workbook"> <book> <xsl:apply-templates select="Worksheet" /> </book> </xsl:template> <!-- シートの書き出し --> <xsl:template match="Worksheet"> <xsl:element name="@Name"> <xsl:apply-templates select="Table/Row"> <xsl:with-param name="sheetName" select="@Name"/> </xsl:apply-templates> </xsl:element> </xsl:template> <xsl:template match="Row\[position()=1\]"> </xsl:template> <!-- 行の書き出し --> <xsl:template match="Row"> <xsl:param name="sheetName" /> <row> <xsl:apply-templates select="Cell"> <xsl:with-param name="sheetName" select="$sheetName"/> </xsl:apply-templates> </row> </xsl:template> <!-- セルの書き出し --> <xsl:template match="Cell"> <xsl:param name="sheetName" /> <xsl:variable name="rowIndex" select="position()"/> <xsl:variable name="nodename" select="/Workbook/Worksheet\[@Name=$sheetName\]/Table/Row\[1\]/Cell\[$rowIndex\]/Data"/> <xsl:variable name="data" select="Data"/> <xsl:if test="$nodename!=''"> <xsl:if test="$data!=''"> <xsl:element name="{$nodename}"> <xsl:value-of select="$data" /> </xsl:element> </xsl:if> </xsl:if> </xsl:template> </xsl:stylesheet>

2007年3月15日 · Toshimitsu Takahashi

XSLT Tips

XMLをまるごとコピー 1 2 3 4 5 6 7 8 9 10 11 12 13 <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="*"> <xsl:copy> <xsl:for-each select="@*"> <xsl:copy /> </xsl:for-each> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet> ノード名の取得(カレントノードが mx:Canvas だったとき) 1 <xsl:value-of select="local-name()" /> Canvas となる ...

2007年3月7日 · Toshimitsu Takahashi