首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ansible从列表中读取XML属性

使用ansible从列表中读取XML属性
EN

Stack Overflow用户
提问于 2019-04-08 17:34:16
回答 2查看 1.8K关注 0票数 0

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

代码语言:javascript
复制
<?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>中读取元素似乎很容易,但我不知道如何从<PropertySection>中读取特定的Property

代码语言:javascript
复制
- 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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-04-08 18:06:34

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

代码语言:javascript
复制
xpath: '/a:Environment/a:PropertySection/a:Property'

不幸的是,在这种情况下,来自xml模块的返回值有点难以处理;我们获得了如下数据结构:

代码语言:javascript
复制
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"
            }                                                                                                                                                                                  
        }           
    ]         
}                                

恶心,对吧?但是,我们可以通过一点黑客操作,把它按摩成一个更有用的结构:

代码语言:javascript
复制
---
- 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

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

代码语言:javascript
复制
ok: [localhost] => {
    "properties": {
        "dns": "test.myeng.com", 
        "dns-servers": "8.8.8.8", 
        "gateway": "192.168.100.1", 
        "mask": "255.255.255.0"
    }
}

因此,我们可以访问这样的单个属性:

代码语言:javascript
复制
- debug:
    msg: "The gateway address is {{ properties.gateway }}"

上面的set_fact任务有点毛茸茸的。我们正在利用defaultcombine过滤器来构建一个字典;简化后的版本如下所示:

代码语言:javascript
复制
---
- 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
票数 1
EN

Stack Overflow用户

发布于 2021-06-09 17:22:20

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

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

下面的代码实现了对python3的处理:

代码语言:javascript
复制
- 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 }}"
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55578830

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档