首页 > 解决方案 > 如何在 Ansible 中用“复杂”节点替换 XML 节点?

问题描述

如何使用 xml 模块,是幂等的(运行两次时没有“更改”)来达到示例所需的状态?

例子:

初始状态,bar节点只包含文本:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <foo>foo</foo>
  <bar>bar</bar>
  <baz>baz</baz>
</root>

所需状态,bar节点包含:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <foo>foo</foo>
  <bar name="bar">
     <content name="1" type="text">lorem</content>
     <content name="2" type="yml">lorem: ipsum</content>
     </verbose>
  </bar>
  <baz>baz</baz>
</root>

我的尝试:

---
- hosts: localhost
  vars:
    xml_text: >-
      <?xml version='1.0' encoding='UTF-8'?>
      <root>
        <foo>foo</foo>
        <bar><barbar/></bar>
        <baz>baz</baz>
      </root>
  tasks:
    - name: "Substitute bar. Bad: wipes the other nodes"
      xml:
        xmlstring: "{{ xml_text }}"
        xpath: /root
        input_type: xml
        set_children: |-
          <bar>
            <verbose />
            <content name="1" type="text">lorem</content>
            <content name="2" type="yml">lorem: ipsum</content>
          </bar>
      register: result

    - debug:
        var: result

    # Imitating https://github.com/ansible-collections/community.general/blob/main/tests/integration/targets/xml/tasks/test-set-children-elements-level.yml
    - name: "Substitute bar. Bad: Can't do both tags ans values"
      xml:
        xmlstring: "{{ xml_text }}"
        xpath: /root/bar
        input_type: yaml
        set_children:
            - verbose: "1"
            - content:
                name: "1"
                type: text
            #     _ : lorem
            #     "": lorem
            #     ~ : lorem
            - content: "lorem: ipsum"
            #       name: 2
            #       type: yml
      register: result

    - debug:
        var: result

    - name: "Substitute bar. Bad: Fails"
      xml:
        xmlstring: "{{ xml_text }}"
        xpath: /root/bar
        input_type: xml
        set_children: |-
            <verbose />
            <content name="1" type="text">lorem</content>
            <content name="2" type="yml">lorem: ipsum</content>
      register: result

    - debug:
        var: result

标签: xmlansible

解决方案


我认为您需要对 XML 内容使用空节点(键“_”)。见https://github.com/cmprescott/ansible-xml/issues/101

例如

- name: Configure proxy in maven
xml:
  path: /etc/maven/settings.xml
  namespaces:
    mvn: http://maven.apache.org/SETTINGS/1.0.0
  xpath: /mvn:settings/mvn:proxies
  pretty_print: yes
  set_children:
    - proxy:
        _:
          - id: "proxy"
          - active: "true"
          - protocol: "http"
          - host: '{{ proxied_proxy_node }}'
          - port: '{{ proxied_proxy_port | string }}'
when: maven_settings_file.stat.exists

推荐阅读