Ansible xml模块增删带属性及内容的XML元素配置问题
Ansible 操作 confluence.cfg.xml 增删 property 节点问题解决
我有一个结构如下的 confluence.cfg.xml 文件:
<?xml version='1.0' encoding='UTF-8'?> <confluence-configuration> <setupStep>setupstart</setupStep> <setupType>custom</setupType> <buildNumber>0</buildNumber> <properties> <property name="confluence.database.choice">postgresql</property> <property name="confluence.database.connection.type">database-type-standard</property> <property name="webwork.multipart.saveDir">${localHome}/temp</property> <property name="attachments.dir">${confluenceHome}/attachments</property> </properties> </confluence-configuration>
需要对文件内的多个<property>元素执行新增、删除操作,编写Ansible任务时遇到两类语法问题:
问题1:删除指定节点时误删所有property元素
错误写法
预期仅删除name属性为confluence.database.choice、confluence.database.connection.type的两个property元素,但运行后所有<property>元素都被删除,错误任务代码如下:
- name: "Remove elements" xml: path: "{{ atl_product_home }}/confluence.cfg.xml" xpath: /confluence-configuration/properties/property attribute: name value: - confluence.database.choice - confluence.database.connection.type state: absent
错误原因
Ansible xml模块的value参数不支持传入列表做批量多值匹配,传入列表时匹配规则失效,会直接对xpath选中的所有节点执行删除操作。
正确写法
两种方案可按需选择:
- 循环删除单节点,通过
with_items传入要删除的name值列表,xpath直接写属性匹配规则:
- name: "Remove specified property elements" xml: path: "{{ atl_product_home }}/confluence.cfg.xml" xpath: "/confluence-configuration/properties/property[@name='{{ item }}']" state: absent with_items: - confluence.database.choice - confluence.database.connection.type
- 用xpath的多值匹配规则一次性选中目标节点,无需循环:
- name: "Remove specified property elements" xml: path: "{{ atl_product_home }}/confluence.cfg.xml" xpath: "/confluence-configuration/properties/property[@name='confluence.database.choice' or @name='confluence.database.connection.type']" state: absent
问题2:新增节点时无法同时设置属性和文本内容
错误写法
想要新增类似<property name="foo">bar</property>同时带name属性和文本内容的元素,执行后生成了两个独立元素:<property>bar</property>和<property name="foo"/>,错误任务代码如下:
- name: "Add elements" xml: path: "{{ atl_product_home }}/confluence.cfg.xml" xpath: /confluence-configuration/properties add_children: - property: bar - property: name: foo
错误原因
add_children字段下每一个以-开头的列表项都会被解析为一个独立的子节点,上述写法写了两个property条目,自然会生成两个独立节点。要给单个节点同时配置属性和文本内容,需要把属性、文本值写在同一个property对应的字典结构中,节点文本内容通过保留键_text指定。
正确写法
- 单个节点新增写法:
- name: "Add single property element with attribute and text" xml: path: "{{ atl_product_home }}/confluence.cfg.xml" xpath: /confluence-configuration/properties add_children: - property: name: foo _text: bar
- 批量新增多个节点写法,直接在
add_children下列出所有节点即可:
- name: "Batch add multiple property elements" xml: path: "{{ atl_product_home }}/confluence.cfg.xml" xpath: /confluence-configuration/properties add_children: - property: name: foo _text: bar - property: name: another.key _text: another_value - property: name: third.key _text: third_value
补充:如果要避免重复新增同名节点,可以搭配
state: present参数,或者提前通过xpath判断节点是否存在。
内容的提问来源于stack exchange,提问作者shepster
相关产品推荐
相关产品推荐

