LibXML-Rubyの使い方メモ

以前にLibXML-Rubyのインストールメモを書いてから、大分時間がたってしまったけれども。
ぽつぽつと色々使ってなんとなく分かってきてるので、初歩の使い方を簡単に纏めてみるです。
なにしろ、時間が経つとまた忘れるから><

ちなみに「なにこれ、ここまでは知ってる!」
っていう方はドキュメントへのリンクを置いておきますので、これで許してください><
http://libxml.rubyforge.org/rdoc/index.html

LibXML-Rubyを使う

なにはともあれ、LibXML-Rubyを使うにはまず読み込んでから。
※ちなみにインストールは以前の記事参照で。(libxml-rubyをinstallしてみたメモ

require 'rubygems'
require 'xml/libxml' 

外部のXMLを読み込んだりする場合はopen-uriとかもrequireしておくと幸せになれるかも。

require 'open-uri'

XMLの生成と保存

LibXML-Rubyで新しいXMLを作成したいので、まずは雛形になるXMLを生成してみる

<?xml version="1.0" encoding="UTF-8"?>
<Root/>

こんな感じにとりあえずしたい
ソースが以下な感じ

xml = LibXML::XML::Document.new()
xml.root = LibXML::XML::Node.new( 'Root' )
root = xml.root

もしも、外部のXMLをopen-uriで取得する場合は以下のような感じ

uri = open( 'hogehoge.xml' ) do |f|
  f.read
end
xml = LibXML::XML::Document.string( uri )

生成したXMLを保存してみる

save_dir = 'hoge/hige'
xml.save( save_dir + '/hogehoge.xml', :indent => true, :encoding => LibXML::XML::Encoding::UTF_8 )

内部情報の生成

エレメントと属性の追加を行うには

xml = LibXML::XML::Document.new()
xml.root = LibXML::XML::Node.new( 'Root' )
root = xml.root
root << elem1 = LibXML::XML::Node.new( 'Element1' )
elem1['type'] = 'hoge'
elem1 << 'hige'

生成されたXMLは以下

<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <Element1 type="hoge">hige</Element1>
</Root>

もしも異なるXMLのノードを追加する場合は、以下のように追加する感じ
※そのまま追加しようとすると'Nodes belong to different documents.'になっちゃう

xml_add = LibXML::XML::Document.new()
xml_add << root = xml.copy( true ) # falseの場合はdeepcopyされない

もしも特定のエレメント、またはノードのみをコピーする場合は以下のように追加

root << elemnt = xml.find_first( 'Element1' ).copy( true ) # falseの場合はdeepcopyされない

もしも特定のノードを削除する場合は、以下のような感じ
※例えばrootに含まれるノードのうち、アトリビュートにtypeが存在し、かつ値がhogeの場合にノードを削除する

xml.find( '*' ).each do |node|
  node.attributes.each do |attr|
    if( attr.name == 'type' && attr.value == 'hoge' ) then
      node.remove!
      break
    end
  end
end

内部情報の取得

エレメントの検索及び値の取得してみる
※直接find又はfind_firstからcontetを取得しようとした時、もしも値がない場合NoMethodErrorになるので注意

xml.find_first( 'hoge/hige' ).each do |elem|
  if elem.name == 'hage_element'
    p elem.content
  end
end

上記と結果は同じ

p xml.find_first( 'hoge/hige/hage_element' ).content

属性を取得してみる

xml.find( 'hoge' ).attributes.each do |attr|
  if attr.name == 'type'
    p attr.value
  end
end

上記と結果は同じ

p xml.find_first( 'hoge' ).attributes.get_attribute( 'type' ).value


と、基本的な使い方はこんな感じなのかな。かな。
突っ込みとか追加情報募集中ですます。