Tenarai::XML

Ruby のブロックを使って XML を作るクラス

概要

あたりまえのことなんですが、html ってこんな風に書くじゃないですか、

  1. <html>
  2. <head><title>タイトル</text></head>
  3. <body>
  4. <h1>ヘッダー</h1>
  5. <p id="summary">
  6. コンテンツいろいろ
  7. </p>
  8. </body>
  9. </html>

気をつけて書けばいいんでしょうが、タグが多くなってくると、(これは例なので少ないけど、)

  1. <html>
  2. <head><title>タイトル</text></head>
  3. <body>
  4. <h1>ヘッダー</h1>
  5. <p id="summary">
  6. コンテンツいろいろ
  7. <div>
  8. </p>
  9. コンテンツそれから...
  10. </div>
  11. <body>
  12. </html>

こんな風に div と p の入れ子がおかしなことになったり、閉じタグを間違って書いちゃったりします。この例だと body の閉じタグも間違ってます。

チェックすればいいんだけど、めんどうなんで、出来れば生の XML や HTML は触りたくない。

そこで、Ruby でこういう風に書ければ便利かなと思って作りました。 タイプ量は増えちゃいますが...

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.tag('html') do |html|
  4. html.tag('head').tag('title').text('タイトル')
  5. html.tag('body') do |bd|
  6. bd.tag('h1').text('ヘッダー')
  7. bd.tag('p') do |p|
  8. p['id'] = 'summary'
  9. p.text('コンテンツいろいろ')
  10. end
  11. bd.tag('div').text('コンテンそれから...')
  12. end
  13. end
  14. puts xml.to_s

これを実行すると、以下のようにデフォルトでは 2 文字でインデントします。また、テキストの両側に不要なスペースや改行文字を付けません。

  1. <html>
  2. <head>
  3. <title>タイトル</title>
  4. </head>
  5. <body>
  6. <h1>ヘッダー</h1>
  7. <p id="summary">コンテンツいろいろ</p>
  8. <div>コンテンそれから...</div>
  9. </body>
  10. </html>

Tenarai::XML.new と to_s の引数にインデント文字数を指定できるので、例えば最初の方の new するところをこうするか、

  1. xml = Tenarai::XML.new(:indent => 0)

あるいは、最後の行を、

  1. puts x.to_s(0)

とすると、

  1. <html><head><title>タイトル</title></head><body><h1>ヘッダー</h1><p id="summary">コンテンツいろいろ</p><div>コンテンそれから...</div></body></html>

インデントしないで、こんな風に一行にします。

このモジュールを書いた後、どっかで同じようなものを見たような気がするんですが、書いてしまったものはしょうがない。もったいないので、使うことにします。

クラスメソッド

new(param={:indent=>2})

new(param={:indent=>2}) { |xml| ... }

それぞれ、オブジェクトを作成します。引数のハッシュオブジェクトにデフォルトのインデント文字数を指定することが出来ます。また、ブロックを指定した場合は、ブロックの引数に作成したオブジェクトが代入されます。

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.tag('a').tag('b')
  4. puts xml.to_s
  5. puts Tenarai::XML.new { |xml|
  6. xml.tag('a').tag('b')
  7. }.to_s

メソッド

xml(version, encoding)

xml 宣言を作成します。

サンプルコード

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.xml('1.0', 'utf-8')
  4. puts xml.to_s

実行結果

<?xml version="1.0" encoding="utf-8"?>

doctype(root, fpi, uri)

DOCTYPE 宣言を作成します。

サンプルコード

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.doctype('html', '-//W3C//DTD XHTML 1.0 Strict//EN', 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd')
  4. puts xml.to_s

実行結果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

tag(tag, attr={})

tag(tag, attr={}) { |obj| ... }

それぞれタグオブジェクト (Tenarai::XML::Tag) を作成します。引数としてタグのアトリビュートを指定した Hash オブジェクトを渡すことができます。ブロックを指定した場合は、ブロックの引数に作成したタグオブジェクトが代入されます。

タグオブジェクトの [], []= メソッドでアトリビュートを操作できます。

Tenarai::XML::Tag クラスは Tenarai::XML クラスを継承しているので、Tenarai::XML クラスのメソッドを使ってタグを入れ子にしたり、テキストノードを作成したりすることができます。

サンプルコード

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.tag('html') do |html|
  4. html.tag('head').tag('title').text('タイトル')
  5. html.tag('body') do |bd|
  6. bd.tag('h1', 'id' => 'title').text('ヘッダー')
  7. bd.tag('p') do |p|
  8. p['class'] = 'summary'
  9. p.text('コンテンツ概要')
  10. end
  11. end
  12. end
  13. puts xml.to_s

実行結果

  1. <html>
  2. <head>
  3. <title>タイトル</title>
  4. </head>
  5. <body>
  6. <h1 id="title">ヘッダー</h1>
  7. <p class="summary">コンテンツ概要</p>
  8. </body>
  9. </html>

text(text)

テキストを作成します。< や > などは to_s したときにエスケープされます。

空白文字を &nbsp; に変換することはしません。というのも、&nbsp; の場合はブラウザが自動改行してくれないので、ものすごく長い一行になってしまうことになるので。

サンプルコード

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.tag('p').text('<span>テキスト</span>文字 で す')
  4. puts xml.to_s

実行結果

  1. <p>&lt;span&gt;テキスト&lt;/span&gt;文字 で す</p>

escaped_text(text)

テキストを作成します。< や > などは to_s してもそのまま出力されます。

サンプルコード

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.tag('p').escaped_text('<span>テキスト</span>文字 で す')
  4. puts xml.to_s

実行結果

  1. <p><span>テキスト</span>文字 で す</p>

code(code='')

escaped_text と同じでテキストを作成しますが、to_s したときに code の最初と最後に改行文字を付けます。escaped_text だとJavaScript を埋め込んだときに JavaScript コードの最初と最後が script タグにくっついてしまい、見栄えが良くないので用意したメソッドです。ただそれだけ。

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.tag('script', 'type' => 'text/javascript').code <<END
  4. alert('hello');
  5. END
  6. puts xml.to_s

実行結果

  1. <script type="text/javascript">
  2. alert('hello');
  3. </script>

comment(comment)

<!-- --> で囲われたコメントを作成します。

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.comment('コメント文字列')
  4. puts xml.to_s

実行結果

  1. <!--
  2. コメント文字列
  3. -->

cdata(cdata)

CDATA セクションを作成します。

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new
  3. xml.comment('<タグはそのまま出力されます>')
  4. puts xml.to_s

実行結果

  1. <![CDATA[<タグはそのまま出力されます>]]>

to_s(indent=nil)

オブジェクトを XML に整形した文字列を返します。引数にインデントの文字数を指定することができます。

  1. require 'tenarai/xml'
  2. xml = Tenarai::XML.new(:indent => 2)
  3. xml.tag('div').tag('p').text('コンテンツ')
  4. puts xml.to_s
  5. puts xml.to_s(0)

実行結果

  1. <div>
  2. <p>コンテンツ</p>
  3. </div>
  4. <div><p>コンテンツ</p></div>

to_xml

to_s のエイリアスです


AdSense is disabled. Please check setting.