vagrantでやり直しを可能にする

間違えてファイルを消してしまった。

パッケージをインストールたら動かなくなった。元に戻したい。

 

そういった前の状態に戻したいというときに使えるのがsaharaプラグインです。

 

saharaはロールバック、コミットすることができるvagrantプラグインです。

インストール

$ vagrant plugin install sahara
Installing the 'sahara' plugin. This can take a few minutes...
Installed the plugin 'sahara (0.0.16)'!

インストールできたか確認

$ vagrant plugin list
sahara (0.0.16)
vagrant-login (1.0.1, system)
vagrant-share (1.0.1, system)
vagrant-vbguest (0.10.0)

vagrant fileの作成

$ Vagrantfile
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define :centos2 do |dev|
    dev.vm.box               = "chef/centos-6.5"
    dev.vm.hostname          = "dev102"
    dev.vm.network :private_network, ip: "10.0.0.102"
  end
end

コミットとロールバックの実験

# 構築
$ vagrant up centos2
 
$ vagrant sandbox on centos2
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
 
# vimのインストール
$ vagrant ssh centos2
[vagrant@dev102 ~]$ vim --version
-bash: vim: command not found
[vagrant@dev102 ~]$ sudo yum install vim
[vagrant@dev102 ~]$ vim --version
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Apr  5 2012 10:17:30)
[vagrant@dev102 ~]$ exit
 
# コミット
$ vagrant sandbox commit centos2
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
 
# screenのインストール
$ vagrant ssh centos2
[vagrant@dev102 ~]$ screen -v
-bash: screen: command not found
[vagrant@dev102 ~]$ sudo yum install screen
[vagrant@dev102 ~]$ screen -v
Screen version 4.00.03 (FAU) 23-Oct-06
[vagrant@dev102 ~]$ exit
 
$ vagrant sandbox rollback centos2
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
 
# 確認
$ vagrant ssh centos2
[vagrant@dev102 ~]$ screen -v
-bash: screen: command not found
[vagrant@dev102 ~]$ vim --version
VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Apr  5 2012 10:17:30)
$ vagrant sandbox off centos2
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%

インストールし後にcommitにしたvimは入っています。

インストールし後にrollbackしたscreenは入ってません。

便利!

参考URL

https://github.com/jedi4ever/sahara

kindle版の457ページあたりの『応用:OSのロールバックを可能にする - sahara』のところ

オフライン環境でもvagrantを使って開発がしたい

private_networkを使ってvagrant upしたらエラーが出たので、手順化しました。

The specified host network collides with a non-hostonly network!

This will cause your specified IP to be inaccessible. Please change

the IP or name of your host only network so that it no longer matches that of

a bridged or non-hostonly network.

 

検証環境

ホストOS:windows8.1

ゲストOS:CentOS

仮想化ツール:VirtualBoxVagrant

ホストオンリーネットワークの作成

ファイル(F)→環境設定(P)→ネットワーク→ホストオンリーネットワーク(H)
→ホストオンリーネットワークの追加
VirtulBox Host-Only Ehthernet Adapterをダブルクリック
IPv4アドレス(I):10.0.0.1
IPv4ネットマスク(M):255.255.255.0
を設定

f:id:katashiyo515:20140511151427j:plain

Vagrantfileの作成

ネットワークの設定はpublic_networkではなくprivate_networkを使います

ipアドレスは10.0.0.101にしました。

$ vim Vagrantfile
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define :centos do |dev|
    dev.vm.box               = "chef/centos-6.5"
    dev.vm.hostname          = "dev101"
    dev.vm.network :private_network, ip: "10.0.0.101"
  end
end

構築

$ vagrant up centos

ホストをオフラインに設定

右からシャッとだして、オフラインに設定します。

f:id:katashiyo515:20140511151505j:plain

接続

$ ssh vagrant@10.0.0.101
vagrant@10.0.0.101's password:
Last login: Sun May 11 05:38:59 2014 from 10.0.0.1
[vagrant@dev101 ~]$

無事接続できました。

参考URL

Leandro Facchinetti | Vagrant host-only network troubleshooting

gitlabの構築

CentOSでgitlabの構築をします

サーバの用意

vagrantcentos環境を作ります

$ vim Vagrantfile
VAGRANTFILE_API_VERSION = "2"
  
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define :"cent1" do |dev|
    dev.vm.box               = "chef/centos-6.5"
    dev.vm.hostname          = "192.168.1.150"
    dev.vm.network :public_network, ip: "192.168.1.150"
  end
end
 
$ vagrant box add chef/centos-6.5
$ vagrant up
$ vagrant ssh

gitlabのインストール

Ubuntu,Debian,CentOSのパッケージがあります
https://www.gitlab.com/downloads/ 

[vagrant@192 ~]$ wget https://downloads-packages.s3.amazonaws.com/centos-6.5/gitlab-6.8.1_omnibus.4-1.el6.x86_64.rpm
[vagrant@192 ~]$ sudo rpm -ivh gitlab-6.8.1_omnibus.4-1.el6.x86_64.rpm
[vagrant@192 ~]$ sudo gitlab-ctl reconfigure

確認

ブラウザから接続

http://192.168.1.150/

アカウントとパスはこれでログインできます

User: admin@local.host またはroot
Pass: 5iveL!fe

f:id:katashiyo515:20140510132325j:plain

その他

ポートの変更
# 設定ファイルの作成
$ sudo vi /etc/gitlab/gitlab.rb
external_url "http://localhost:8081"
# 設定簿確認
$ sudo gitlab-ctl show-config
# 再設定
$ sudo gitlab-ctl reconfigure
# ブラウザから確認
http://localhost:8081

※reconfigureを実行直後は以下のエラーが出ますが、しばらく待つと接続できるようになります。

502
GitLab is not responding.
リスタート
$ sudo /opt/gitlab/bin/gitlab-ctl restart
ok: run: nginx: (pid 8192) 1s
ok: run: postgresql: (pid 8198) 0s
ok: run: redis: (pid 8207) 0s
ok: run: sidekiq: (pid 8213) 0s
ok: run: unicorn: (pid 8218) 0s
nginxとpostgre使ってます
バックアップ
# バックアップ
$ sudo gitlab-rake gitlab:backup:create
  
# バックアップファイル
$ sudo ls /var/opt/gitlab/backups/
1399691748_gitlab_backup.tar
 
# リストア
sudo gitlab-rake gitlab:backup:restore

参考URL

GitLab | GitLab Community Edition

GitLab.org / GitLab Community Edition | GitLab

ChefServerでjenkins構築

chef serverを使ってjenkinsを構築します。

vagrantでjenkinsをインストールするサーバを作成

$ vagrant up centos

Vagrantfile

1
2
3
4
5
6
7
8
VAGRANTFILE_API_VERSION "2"
Vagrant.configure(VAGRANTFILE_API_VERSIONdo |config|
  config.vm.define :centos do |dev|
    dev.vm.box               = "chef/centos-6.5"
    dev.vm.hostname          = "192.168.1.150"
    dev.vm.network :public_network, ip: "192.168.1.150"
  end
end

Opscode Communityからjenkinsのcookbookを取得

# 確認 
$ knife cookbook site  show jenkins
# インストール
$ knife cookbook site install jenkins

chef serverにcookbookを登録

$ knife cookbook upload jenkins --include-dependencies

clientをserverに登録

$ knife bootstrap 192.168.1.150 -x vagrant -P vagrant --sudo

clientにレシピを登録

$ knife node run_list add 192.168.1.150 \
'recipe[jenkins::java],recipe[jenkins::master]'

clientにレシピをインストール

$ knife ssh name:192.168.1.150 'sudo chef-client' -x vagrant -P vagrant

ブラウザから確認

http://192.168.1.150:8080/

f:id:katashiyo515:20140501002611j:plain

おわり

ChefServerによるサーバー管理

手順通りにインストールしたのにうまくいかない。。

 

うまくはいくけど、手順長すぎ、あと何台構築しないといけないんだろうか。。

 

なんかバグが出た、このサーバだけ設定が古いせいか、ちゃんとアップデートしといてよ。。

 

サーバーの構築作業は何かとめんどくさいことが多いです。

今回はそういった問題を解決してくれる便利ツールChefを使ってみました。

構成

Chef Serverは以下の3種類で構成されています。

・Chef Server:レシピやクライアントを管理します

・Chef Client:レシピを使って構築します

・Workstation:レシピの登録やクライアントの追加をします

※レシピ:サーバを構築するための設定です

 

Chef Soloなどほかの構成はこちらがわかりやすかったです。

Chef Soloと Knife Soloでの ニコニコサーバー構築 (2) 〜導入編〜:dwango エンジニア ブロマガ:ドワンゴ研究開発チャンネル(ドワンゴグループのエンジニア) - ニコニコチャンネル:生活

下準備

VagrantでServer、Clinet、Workstationにするサーバを作ります。

vimとscreenを入れているのは趣味です。Chefには使いません。

$ vim Vagrantfile

VAGRANTFILE_API_VERSION = "2"

 

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

 

  config.vm.define :chefs do |dev|

    dev.vm.box               = "chef/centos-6.5"

    dev.vm.network :public_network, ip: "192.168.1.140"

    dev.vm.hostname          = "192.168.1.140"

    # provisioning

    dev.vm.provision "shell" do |s|

      s.inline  = ""

      s.inline += "sudo yum install screen -y;"

      s.inline += "sudo yum install vim -y;"

    end

  end

 

  config.vm.define :chefc do |dev|

    dev.vm.box               = "chef/centos-6.5"

    dev.vm.network :public_network, ip: "192.168.1.141"

    dev.vm.hostname          = "192.168.1.141"

    # provisioning

    dev.vm.provision "shell" do |s|

      s.inline  = ""

      s.inline += "sudo yum install screen -y;"

      s.inline += "sudo yum install vim -y;"

    end

  end

 

  config.vm.define :work do |dev|

    dev.vm.box               = "chef/centos-6.5"

    dev.vm.network :public_network, ip: "192.168.1.142"

    dev.vm.hostname          = "192.168.1.142"

    # provisioning

    dev.vm.provision "shell" do |s|

      s.inline  = ""

      s.inline += "sudo yum install screen -y;"

      s.inline += "sudo yum install vim -y;"

    end

  end

 

end

$ vagrant box add chef/centos-6.5
$ vagrant up 

今回はすべてCentOSで作っていますが、UbuntuなどほかのOSももちろん使えます。

・Chef Server:192.168.1.140:CentOS

・Chef Client:192.168.1.141:CentOS

・Workstation:192.168.1.142:CentOS

Chef Server(192.168.1.140)を構築

[192.168.1.140] $ wget https://opscode-omnibus-packages.s3.amazonaws.com/el/6/x86_64/chef-server-11.0.12-1.el6.x86_64.rpm
[192.168.1.140] $ sudo rpm -ivh chef-server-11.0.12-1.el6.x86_64.rpm
[192.168.1.140] $ sudo chef-server-ctl reconfigure

使っているOSに応じてインストール方法が違います。

こちらを参考に。Install Chef | Chef

Workstation(192.168.1.142)の構築

knifeをインストール。

最新バージョンだとエラーになるため、旧バージョンをインストールしました。

[192.168.1.142] $ wget https://www.opscode.com/chef/install.sh
[192.168.1.142] $ sudo bash install.sh -v 11.4.0

レポジトリ作成

[192.168.1.142] $ sudo yum install git
[192.168.1.142] $ git clone git://github.com/opscode/chef-repo.git
[192.168.1.142] $ mkdir -p ~/chef-repo/.chef
[192.168.1.142] $ cd chef-repo
[192.168.1.142] $ echo '.chef' >> .gitignore

Chef Server(192.168.1.140)から鍵を持ってくる

[192.168.1.140]$ sudo scp /etc/chef-server/chef-validator.pem vagrant@192.168.1.142:/home/vagrant/chef-repo/.chef/validation.pem

[192.168.1.140]$ sudo scp /etc/chef-server/admin.pem vagrant@192.168.1.142:/home/vagrant/chef-repo/.chef/

鍵の権限を変更 

[192.168.1.142] $ sudo chown vagrant:vagrant ~/.chef/*.pem

knifeの初期化

[192.168.1.142] $ knife configure --initial
WARNING: No knife configuration file found
Where should I put the config file? [/home/vagrant/.chef/knife.rb]
Please enter the chef server URL: http://192.168.1.142:4000 https://192.168.1.140
Please enter a name for the new user: [vagrant]
Please enter the existing admin name: [admin]
Please enter the location of the existing admin's private key: [/etc/chef/admin.pem] ~/chef-repo/.chef/admin.pem
Please enter the validation clientname: [chef-validator]
Please enter the location of the validation key: [/etc/chef/validation.pem] ~/chef-repo/.chef/validation.pem
Please enter the path to a chef repository (or leave blank): ~/chef-repo
Creating initial API user...
Please enter a password for the new user:
Created user[vagrant]
Configuration file written to /home/vagrant/.chef/knife.rb

レシピの作成

サンプルの手順通りアパッチのレシピを作ります

[192.168.1.142] $ knife cookbook create apache_tutorial

 apacheのパッケージを入れる設定

 [192.168.1.142] $ vim ~/chef-repo/cookbooks/apache_tutorial/recipes/default.rb

package "httpd" do

  action :install

end

 

service "httpd" do

  action [ :enable, :start ]

end

 

cookbook_file "/var/www/html/index.html" do

  source "index.html"

  mode "0644"

end

 Hello Worldを表示するhtmlファイルを作る

[192.168.1.142] $ vim ~/chef-repo/cookbooks/apache_tutorial/files/default/index.html

<html>

<body>

  <h1>Hello, world!</h1>

</body>

</html>

knifeでサーバにレシピを登録する

[192.168.1.142] $ knife cookbook upload apache_tutorial

サーバで登録したレシピを確認

https://192.168.1.140/

ログイン

Username:admin

Password:p@ssw0rd1

 

無事apache_tutorialのレシピが登録されています。

f:id:katashiyo515:20140420190148j:plain

クライアント登録

サーバにクライアントを登録します。

[192.168.1.142] $ knife bootstrap 192.168.1.141 -x vagrant -P vagrant --sudo

無事登録されました。

f:id:katashiyo515:20140420190351j:plain

クライアントにレシピを登録する

WorkStationから実行します

[192.168.1.142] $ knife node run_list add 192.168.1.141 'recipe[apache_tutorial]'

 サーバの画面からでも可能です。

以下の画面でAvailable RecipesからRun Listにドラッグ&ドロップをするだけ。

f:id:katashiyo515:20140420190614j:plain

f:id:katashiyo515:20140420190558j:plain

追加できました。

f:id:katashiyo515:20140420190807j:plain

レシピを反映する

[192.168.1.142] knife ssh name:192.168.1.141 'sudo chef-client' -P vagrant

レシピが反映されたか確認

WEBからアクセスするとHello Worldと表示され、作ったレシピ通りに動いています。

f:id:katashiyo515:20140420190953j:plain

 

Chefいいね!

参考

入門 Chef Server #biglobetechtalk :かなり参考になりました

All about Chef ... — Chef Docs

Chef Soloと Knife Soloでの ニコニコサーバー構築 (2) 〜導入編〜:dwango エンジニア ブロマガ:ドワンゴ研究開発チャンネル(ドワンゴグループのエンジニア) - ニコニコチャンネル:生活

トラブルシューティング

$ sudo knife configure initial

WARNING: No knife configuration file found

Where should I put the config file? [/root/.chef/knife.rb]

ERROR: Ohai::Exceptions::DependencyNotFound: Can not find a plugin for dependency os

→バグらしいので旧バージョンをインストールする

https://tickets.opscode.com/browse/CHEF-5211

http://www.sharkpp.net/blog/2014/04/18/first-step-chef.html

vagrantで開発環境を整える

vagrantはdockerのようにべき等性のある開発環境を作ることができます。

dockerはコンテナ型の仮想化であるのに対し、vagrantVirtualBoxVMWareHyper-Vを利用しているのでホスト型とハイパーバイザー型の仮想化です。

 

ようは、WindowsMacで簡単にlinux環境を作ったり壊したりできるとても便利なツールです。

 

ではではWindows環境でCentOSFedoraDebianUbuntu環境を作ってみます。

 

インストール

ここから環境にあったものをダウンロードしてインストール

ruby gemもあるがバージョンが古い。

 

あとVirtualBoxもインストールする

VirtualBoxで64bitのOSが入れられなかくなるのでHyper-VはOFFにします。

 

sshクライアントはPuTTY ごった煮版を使いました。

試しにubuntu環境を作る

コマンドプロンプトを起動(windowsキー→cmdと打つ→Enter)し以下のコマンドを実行。

> mkdir test

> cd test

> vagrant init hashicorp/precise32

> vagrant up 

それぞれのコマンドがやっていることはこんなイメージ。

vagrant init hashicorp/precise32

ubuntuの32bit(hashicorp/precise32)のイメージをダウンロードし、Vagrantfileを初期化。

vagrant up

Vagrantfileを読み込みVirtualBoxubuntu環境を作成。

仮想環境にログインする

> vagrant ssh 

`ssh` executable not found in any directories in the %PATH% variable. Is an
SSH client installed? Try installing Cygwin, MinGW or Git, all of which
contain an SSH client. Or use the PuTTY SSH client with the following
authentication information shown below:
 
Host: 127.0.0.1
Port: 2222
Username: vagrant

 SSHクライアントがないので怒られる。Cygwinなどで起動していればこれでログインできるはず。

今回はPuttyを使ってログインします。必要な情報はこれです。

Host: 127.0.0.1

Port: 2222

Username: vagrant

ホスト名:127.0.0.1

ポート:2222

ユーザ:vagrant

パス:vagrant

でログインできます。

vagrant@precise32:~$ lsb_release -a

No LSB modules are available.

Distributor ID: Ubuntu

Description:    Ubuntu 12.04 LTS

Release:        12.04

Codename:       precise 

 ubutu環境の出来上がりです。

他の環境も作る

vagrantはOSを『box』で管理しています。

ではCentOSFedoraDebianUbuntuのboxをvagrantcloudから取得します。

# ダウンロード
> vagrant box add chef/centos-6.5
vagrant box add chef/ubuntu-13.10
vagrant box add chef/debian-7.4
> vagrant box add chef/fedora-20

# 確認

>vagrant box list
chef/centos-6.5     (virtualbox, 1.0.0)
chef/debian-7.4     (virtualbox, 1.0.0)
chef/fedora-20      (virtualbox, 1.0.0)
chef/ubuntu-13.10   (virtualbox, 1.0.0)
hashicorp/precise32 (virtualbox, 1.0.0)

 Vagrantfileを作る

 

vagrant init
notepad Vagrantfile 

VAGRANTFILE_API_VERSION = "2"
 
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define :centos do |dev|
    dev.vm.box               = "chef/centos-6.5"
  end
 
  config.vm.define :debian do |dev|
    dev.vm.box               = "chef/debian-7.4"
  end
 
  config.vm.define :fedora do |dev|
    dev.vm.box               = "chef/fedora-20"
  end
 
  config.vm.define :ubuntu do |dev|
    dev.vm.box               = "chef/ubuntu-13.10"
  end
end

dev.vm.boxにbox名を指定します。

VirtuabBoxに環境を作る

> vagrant up

VirtuabBoxに環境ができました。

f:id:katashiyo515:20140420075955j:plain

プロビジョニング

デフォルトではscreenやvimが入っていません。Vagrantfileを修正して入れます。

centosだけvimとscreenをインストールする設定をします。

> notepad Vagrantfile


VAGRANTFILE_API_VERSION = "2"
 
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define :centos do |dev|
    dev.vm.box               = "chef/centos-6.5"
    dev.vm.provision "shell" do |s|
      s.inline  = ""
      s.inline += "sudo yum install screen -y;"
      s.inline += "sudo yum install vim -y;"
    end
  end
 
  config.vm.define :debian do |dev|
    dev.vm.box               = "chef/debian-7.4"
  end
 
  config.vm.define :fedora do |dev|
    dev.vm.box               = "chef/fedora-20"
  end
 
  config.vm.define :ubuntu do |dev|
    dev.vm.box               = "chef/ubuntu-13.10"
  end
end

起動しているboxの設定を読み込みなおすには『up』コマンドではなく『reload』コマンドを使います。

vagrant reload centos --provision

 centosのみプロビジョニングも含めて再設定するため、『centos --provision』と書いています。

$ screen -v

Screen version 4.00.03 (FAU) 23-Oct-06 

$ vim --version

VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Apr  5 2012 10:17:30)

 無事インストールできました。

そのほかコマンド

vagrantの終了

 vagrant destroy

vagrantの中断

vagrant suspend
vagrantの再開

vagrant resume

boxの作成

vagrant package --base CentOS64
vagrant box add  kashi/centos package.box

※実行前にVirtualBox上でCentOS64という名前の仮想環境を作る必要があります。

boxの削除

vagrant box remove hashicorp/precise32 virtualbox

資料

Vagrant

Vagrant日本語ドキュメント

Vagrant Cloud

xmlのパースがしたい!nokogiri

RubyxmlやhtmlのパースするためにNokogiriの使い方を調べました。

インストール

gemからインストールできます。

gem install nokogiri

パース

・直接パース

html = "<html><body><h1>Mr. Belvedere Fan Club</h1></body></html>"

html_doc = Nokogiri::HTML(html)

xml_doc  = Nokogiri::XML("<root><aliens><alien><name>Alf</name></alien></aliens></root>") 

puts html_doc

puts xml_doc

 結果

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">

<html><body><h1>Mr. Belvedere Fan Club</h1></body></html>

<root>

  <aliens>

    <alien>

      <name>Alf</name>

    </alien>

  </aliens>

</root>

・ファイルからパース

f = File.open("test.xml")

doc = Nokogiri::XML(f)

f.close

puts doc

結果 

<?xml version="1.0"?>

<sushi>

<ikura>very good</ikura>

<saba>good</saba>

</sushi>

・urlからパース

require 'open-uri'

doc = Nokogiri::HTML(open("http://yahoo.co.jp"))

puts doc.title

 実行結果

Yahoo! JAPAN

・自動で補完する

</b>がないので通常であればエラーになるはずが、、

doc = Nokogiri::XML('<a><b>b<c>c</c></a>')

puts doc

<?xml version="1.0"?>

<a>

  <b>b<c>c</c></b>

</a>

 勝手に補完してくれます。

・パースするときのオプション

xmlの構文が間違っているときエラーにしたい場合はオプションをつけて読み込みます

doc = Nokogiri::XML('<a><b>b<c>c</c></a>') do |config|

config.strict

end

puts doc

実行するとちゃんとエラーになります

/opt/ruby-1.9.3-p545/lib/ruby/gems/1.9.1/gems/nokogiri-1.6.1/lib/nokogiri/xml/document.rb:55:in `read_memory': Premature end of data in tag a line 1 (Nokogiri::XML::SyntaxError)

        from /opt/ruby-1.9.3-p545/lib/ruby/gems/1.9.1/gems/nokogiri-1.6.1/lib/nokogiri/xml/document.rb:55:in `parse'

        from /opt/ruby-1.9.3-p545/lib/ruby/gems/1.9.1/gems/nokogiri-1.6.1/lib/nokogiri/xml.rb:33:in `XML'

        from noko.rb:43:in `<main>'

■検索

・<b></b>で囲まれたタグを取得

コード

doc = Nokogiri::XML('<a><b>b1</b><b>b2</b><c><b>b3</b></c></a>')

puts doc

puts doc.xpath("//b")

パースしたxml

<?xml version="1.0"?>

<a>

  <b>b1</b>

  <b>b2</b>

  <c>

    <b>b3</b>

  </c>

</a>

結果

<b>b1</b>

<b>b2</b>

<b>b3</b>

・特定のタグを取得

コード

doc = Nokogiri::XML('<a><b>b1</b><b>b2</b><c><b>b3</b></c></a>')

puts doc

puts doc.xpath("/a/b")[1]

 パースしたxml

<?xml version="1.0"?>

<a>

  <b>b1</b>

  <b>b2</b>

  <c>

    <b>b3</b>

  </c>

</a>

 結果

<b>b2</b>

・値を取得

コード

doc = Nokogiri::XML('<a><b>b1</b><b>b2</b><c><b>b3</b></c></a>')

puts doc

puts doc.xpath("/a/b")[1].inner_text

パースしたxml 

<?xml version="1.0"?>

<a>

  <b>b1</b>

  <b>b2</b>

  <c>

    <b>b3</b>

  </c>

</a>

結果 

b2

・属性値を取得

コード

doc = Nokogiri::XML('<a><b>b1</b><b src="src_b2">b2</b><c><b>b3</b></c></a>')

puts doc

puts doc.xpath("/a/b")[1].attr("src")

 

 パースしたxml

<?xml version="1.0"?>

<a>

  <b>b1</b>

  <b src="src_b2">b2</b>

  <c>

    <b>b3</b>

  </c>

</a>

 結果

src_b2

■変換

・値の変更

コード

doc = Nokogiri::XML('<a><b>b</b><c>c</c></a>')

puts doc

b = doc.at_css "b"

b.content = "bbbb"

puts doc

 変換前

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

</a>

 変換後

<?xml version="1.0"?>

<a>

  <b>bbbb</b>

  <c>c</c>

</a>

・ノードの移動

コード

doc = Nokogiri::XML('<a><b>b</b><c>c</c></a>')

puts doc

b = doc.at_css "b"

c = doc.at_css "c"

b.parent = c

puts doc 

 変換前

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

</a>

 

 変換後

<?xml version="1.0"?>

<a>

  <c>c<b>b</b></c>

</a>

・ノード移動2

コード

doc = Nokogiri::XML('<a><b>b</b><c>c</c></a>')

puts doc

b = doc.at_css "b"

c = doc.at_css "c"

c.add_next_sibling(b)

puts doc

変換前 

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

</a>

 変換後

<?xml version="1.0"?>

<a>

  <c>c</c>

  <b>b</b>

</a>

・属性の追加

コード

doc = Nokogiri::XML('<a><b>b</b><c>c</c></a>')

puts doc

b = doc.at_css "b"

b['img'] = "bbb.img"

puts doc

変換前

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

</a>

変換後

<?xml version="1.0"?>

<a>

  <b img="bbb.img">b</b>

  <c>c</c>

</a>

・ノードの追加

コード

doc = Nokogiri::XML('<a><b>b</b><c>c</c></a>')

puts doc

d = Nokogiri::XML::Node.new "d", doc

d.content = "ddddd"

c = doc.at_css "c"

c.add_next_sibling(d)

puts doc

変換前 

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

</a>

 変換後

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

  <d>ddddd</d>

</a>

・ラップする

コード

doc = Nokogiri::XML('<a><b>b</b><c>c</c><d>d</d></a>')

puts doc

nodes = doc.css "b,c"

wrapper = nodes.wrap("<test></test>")

puts doc

 

 変換前

<?xml version="1.0"?>

<a>

  <b>b</b>

  <c>c</c>

  <d>d</d>

</a>

 変換後

<?xml version="1.0"?>

<a>

  <test>

    <b>b</b>

  </test>

  <test>

    <c>c</c>

  </test>

  <d>d</d>

</a>

こんな感じでいろいろできます。 

トラブルシューティング

エラー

libexslt.so.0: cannot open shared object file: No such file or directory

対処法:libxsltをインストールする

sudo yum install libxslt