Help us understand the problem. What is going on with this article?

ChefとAnsibleでのxml操作

More than 1 year has passed since last update.

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リソースの内容となる。

参考

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ファイル

/tmp/test.xml
<?xml version="1.1" encoding="UTF-8"?>
<foo>
  <bar>val</bar>
</foo>

更新後xmlファイル

/tmp/test.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]
hiroyuki_onodera
インフラエンジニア。 Ansible, Chef等による自動化、クラスターSW(PowerHA,TSA, pacemaker)などをしています。 このサイトにおける掲載内容はあくまで私自身の見解であり、必ずしも私の所属団体・企業における立場、戦略、意見を代表するものではありません。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした