使用Ansible从列表中读取XML属性

时间:2019-04-08 17:34:17

标签: xml ansible

我想使用ansible从以下文件中读取<PropertySection>下的属性:

<?xml version='1.0' encoding='UTF-8'?>
<Environment xmlns="http://schemas.dmtf.org/ovf/environment/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:oe="http://schemas.dmtf.org/ovf/environment/1" xmlns:ve="http://www.vmware.com/schema/ovfenv" oe:id="" ve:vCenterId="vm-6863">
  <PlatformSection>
    <Kind>VMware ESXi</Kind>
    <Version>6.0.0</Version>
    <Vendor>VMware, Inc.</Vendor>
    <Locale>en</Locale>
  </PlatformSection>
  <PropertySection>
    <Property oe:key="dns" oe:value="test.myeng.com"/>
    <Property oe:key="dns-servers" oe:value="8.8.8.8"/>
    <Property oe:key="gateway" oe:value="192.168.100.1"/>
    <Property oe:key="mask" oe:value="255.255.255.0"/>
  </PropertySection>
  <ve:EthernetAdapterSection>
    <ve:Adapter ve:mac="00:50:56:90:2d:a3" ve:network="VM Network" ve:unitNumber="7"/>
  </ve:EthernetAdapterSection>
</Environment>

<PlatformSection>读取元素似乎很容易,但是我不知道如何从Property读取特定的<PropertySection>

- hosts: localhost
  tasks:
  - name: Read XML
    xml:
      path: /tmp/input.xml
      xpath: /a:Environment/a:PlatformSection/a:Version
      content: text
      namespaces:
        a: http://schemas.dmtf.org/ovf/environment/1
    register: xml_out

  - debug: var=xml_out

2 个答案:

答案 0 :(得分:2)

larsks 的解决方案似乎适合在 Ansible 中使用 VMware 的 vApp 属性的任何人。

但是,我认为该解决方案仅适用于在 python2 上运行 Ansible 时;使用 python3,不支持语法 item.values().0

下面的代码在 python3 上运行:

- ansible.builtin.set_fact:
    properties: >-
      {{ properties | default({}) |
      combine({((item.values() | list)[0].values() | list)[0]:
      ((item.values() | list)[0].values() | list)[1]})
      }}
  loop: "{{ xml_out.matches }}"

答案 1 :(得分:1)

我们可以使用xpath表达式来返回所有属性值:

xpath: '/a:Environment/a:PropertySection/a:Property'

不幸的是,在这种情况下,xml模块的返回值很难使用;我们得到这样的数据结构:

ok: [localhost] => {                                                                                                                                                                  [53/7069]
    "xml_out.matches": [                               
        {                                                                   
            "{http://schemas.dmtf.org/ovf/environment/1}Property": {
                "{http://schemas.dmtf.org/ovf/environment/1}key": "dns", 
                "{http://schemas.dmtf.org/ovf/environment/1}value": "test.myeng.com"
            }                                                                                                                                                                                 
        }, 
        {
            "{http://schemas.dmtf.org/ovf/environment/1}Property": {                                                                                                                           
                "{http://schemas.dmtf.org/ovf/environment/1}key": "dns-servers", 
                "{http://schemas.dmtf.org/ovf/environment/1}value": "8.8.8.8"                                                                                                                  
            }  
        }, 
        {                                                                                                                                                                                      
            "{http://schemas.dmtf.org/ovf/environment/1}Property": {                                                                                                                                           "{http://schemas.dmtf.org/ovf/environment/1}key": "gateway", 
                "{http://schemas.dmtf.org/ovf/environment/1}value": "192.168.100.1"                                                                                                                        }            
        },                                                                                                                                                                                             {                  
            "{http://schemas.dmtf.org/ovf/environment/1}Property": {                                                                                                                                           "{http://schemas.dmtf.org/ovf/environment/1}key": "mask", 
                "{http://schemas.dmtf.org/ovf/environment/1}value": "255.255.255.0"
            }                                                                                                                                                                                  
        }           
    ]         
}                                

好吧,对吧?但是,有了一点黑客,我们就可以将其按摩到更有用的结构中:

---
- hosts: localhost
  gather_facts: false
  tasks:
    - xml:
        path: ./data.xml
        xpath: '/a:Environment/a:PropertySection/a:Property'
        content: attribute
        namespaces:
          a: http://schemas.dmtf.org/ovf/environment/1
      register: xml_out

    - set_fact:
        properties: >-
          {{ properties|default({})|
          combine({item.values().0['{http://schemas.dmtf.org/ovf/environment/1}key']:
          item.values().0['{http://schemas.dmtf.org/ovf/environment/1}value']})
          }}
      loop: "{{ xml_out.matches }}"

    - debug:
        var: properties

从该剧本的输出中可以看到,我们现在有了一个简单的字典:

ok: [localhost] => {
    "properties": {
        "dns": "test.myeng.com", 
        "dns-servers": "8.8.8.8", 
        "gateway": "192.168.100.1", 
        "mask": "255.255.255.0"
    }
}

因此我们可以像这样访问各个属性:

- debug:
    msg: "The gateway address is {{ properties.gateway }}"

上面的set_fact任务有点麻烦。我们利用defaultcombine过滤器来建立字典;一个简化的版本可能看起来像:

---
- hosts: localhost
  gather_facts: false
  vars:
    example:
      - [color, red]
      - [name, alice]
      - [size, medium]
  tasks:
    - set_fact:
        properties: "{{ properties|default({})|combine({item.0: item.1}) }}"
      loop: "{{ example }}"

    - debug:
        var: properties