ChefとAnsibleにおけるxml操作の例を示す。
#Chef
require 'nokogiri'
file '/tmp/test.xml' do
content lazy {
x = File.open(path) { |f| Nokogiri::XML(f, &:noblanks) }
x.at_xpath('/foo/bar').content = 'new_val' # 値の設定
x.at_xpath('/foo') << Nokogiri::XML::Node.new("bar2", x) # 子供の追加
x.at_xpath('/foo/bar2'). content = 'val2' # 値の設定
x.to_xml
}
end
Rubyのnokogiriライブラリーを使用する。
xmlファイルをNokogiri::XML::Documentクラスのオブジェクトとして読み込む。noblanksオプションは、読み込み時にxmlを読みやすくする為のブランクや改行を削除する。ブランクや改行が削除されていれば、最後のto_xml時に適切に整形される。
作成したオブジェクトに.at_xpathなどのメソッドを用いて、xmlのディレクトリーに相当するNokogiri::XML::Nodeオブジェクトを取り出し、そこに対して編集などの操作を行う。
.contentにより値を変更する。値としてnilを指定すると、値は削除される。
<<もしくは.add_child()により子供を追加する。ここで追加する内容は、Nokogiri::XML::Node.newにより作成されたもの。事前に値やその下位の構造を設定しておいてから追加しても良いが、ここでは追加後に値を設定している。
to_xmlにてxmlの文字列を構成する。戻された文字列がこのブロックの戻りとなり、fileリソースの内容となる。
##参考
-
contentや<<(add_child)などの編集機能は以下におけるInstance Methodを参照
Class: Nokogiri::XML::Node -
at_xpathは以下のNodeとNodeSetの検索メソッドを参照
Ruby製の構文解析ツール、Nokogiriの使い方 with Xpath
#Ansible
...
- name: python-lxmlのインストール
yum:
name: python-lxml
- name: 値の設定
xml:
path: /tmp/test.xml
xpath: /foo/bar
value: new_val
pretty_print: yes
- name: 子供と値の追加
xml:
path: "/tmp/test.xml"
xpath: "/foo"
add_children:
- bar2: val2
pretty_print: yes
xmlモジュールを使用するには、前提としてlxmlが導入されていることが必要。
ここでは対象にCentOSを使用しているので、yumモジュールにてpython-lxmlを導入している。
##参考
xml - Manage bits and pieces of XML files or strings
#例
##元xmlファイル
<?xml version="1.1" encoding="UTF-8"?>
<foo>
<bar>val</bar>
</foo>
##更新後xmlファイル
<?xml version="1.1" encoding="UTF-8"?>
<foo>
<bar>new_val</bar>
<bar2>val2</bar2>
</foo>
##Chefのログ出力例
* file[/tmp/test.xml] action create
- update content in file /tmp/test.xml from c2d9db to 9215b3
--- /tmp/test.xml 2018-10-24 04:44:49.442544000 +0000
+++ /tmp/.chef-test20181024-46716-1rk4gup.xml 2018-10-24 04:44:49.452544000 +0000
@@ -1,5 +1,6 @@
<?xml version="1.1" encoding="UTF-8"?>
<foo>
- <bar>val</bar>
+ <bar>new_val</bar>
+ <bar2>val2</bar2>
</foo>
##Ansibleのログ出力例
TASK [python-lxmlのインストール] ****************************************************************
changed: [ansible-xml-centos-7]
TASK [値の設定] ******************************************************************************
changed: [ansible-xml-centos-7]
TASK [子供と値の追加] ***************************************************************************
changed: [ansible-xml-centos-7]