如何在ansible中解析URI的XML响应

问题描述 投票:2回答:5

有一个代码可以调用应用程序的Web服务。

 - uri:
         url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
         method: GET
         content_as_json: true
         password: admin
         user: admin
         validate_certs: no
         return_content: yes
         HEADER_Cookie: "{{login.set_cookie}}"
        register: customerId

      - debug:
          var: customerId.content

样本回复是

"customerId.content": "<listResponse type=\"customer\" count=\"1\"><instance customerId=\"28\" name=\"abc\" customerRefId=\"xyz\" refId1=\"12\" type=\"org\" enabled=\"true\" phone=\"\" fax=\"\" billingZip=\"\" billingAddress=\"\" billingCity=\"\" billingCountry=\"\" billingState=\"\" vendor=\"1\" defaultEmail=\"test\" defaultContactName=\"test\"/></listResponse>"

我想在下一个代码块中访问列表响应。就像我只需要“客户ID”的价值。如何使用ansible实现这一目标

ansible ansible-playbook
5个回答
2
投票

Ansible中没有开箱即用的XML支持。 您可以使用正则表达式过滤器在XML数据中进行一些简单的搜索。 在你的例子中:

- debug: msg="{{ customerId.content | regex_findall('customerId=\"(\d+)\"') }}"

将搜索customerId=\"<number>\"字符串并返回引号中的数字列表。

更新:完整的工作示例:

- hosts: localhost
  gather_facts: no
  vars:
    myvar: "<listResponse type=\"customer\" count=\"1\"><instance customerId=\"28\" name=\"abc\" customerRefId=\"xyz\" refId1=\"12\" type=\"org\" enabled=\"true\" phone=\"\" fax=\"\" billingZip=\"\" billingAddress=\"\" billingCity=\"\" billingCountry=\"\" billingState=\"\" vendor=\"1\" defaultEmail=\"test\" defaultContactName=\"test\"/></listResponse>"
  tasks:
    - debug: msg="{{ myvar | regex_findall('customerId=\"(\d+)\"') }}"

我用ansible 2.1.1.0


2
投票

这与sebaszw的答案类似,但不要求将xml响应写入文件,而是将其存储在变量中。

- uri:
    url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
    method: GET
    content_as_json: true
    password: admin
    user: admin
    validate_certs: no
    return_content: yes
    HEADER_Cookie: "{{login.set_cookie}}"
  register: customerId

- xml:
    xmlstring: "{{customerId.content}}"
    xpath: /listResponse/instance
    content: attribute
  register: instance_attributes

- debug:
    var: instance_attributes.matches.0.instance.customerId 

1
投票

从Ansible 2.4你可以这样做:

- get_url:
    url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
    dest: ./response.xml
    url_password: admin
    url_user: admin
    validate_certs: no
    headers:
      Cookie: "{{login.set_cookie}}"

- xml:
    path: ./response.xml
    xpath: /listResponse/instance
    content: attribute
  register: instance_attributes

- debug:
    var: instance_attributes.matches.0.instance.customerId

0
投票

值得一看ansible-xml。它不是Ansible的一部分,但它是一个非常有用的解析xml的模块,它使用了引擎盖下的lxml Python库。


0
投票

我刚刚在uri模块中添加了XML解析支持,因为我也需要它。 https://github.com/ansible/ansible/pull/53045

就像JSON支持一样,它将返回一个'xml'键,其中包含一个由XML内容组成的字典,以方便访问有效负载中的数据。

您的示例如下所示:

 - uri:
     url: http://10.164.52.61:8080/ems/v74/ws/customer.ws?customerRefId=f4XXXb15d69c3
     method: GET
     password: admin
     user: admin
     validate_certs: no
     HEADER_Cookie: "{{login.set_cookie}}"
    register: customerId

  - debug:
      var: customerId.xml.listResponse.instance['@customerId']

customerId.xml中的输出将是:

{
    'listResponse': {
        '@type': 'customer',
        '@count', '1',
        'instance': {
            '@customerId': '28',
            '@name': 'abc'
            '@customerRefId': 'xyz',
            '@refId1': '12',
            '@type': 'org',
            '@enabled': 'true',
            '@phone': '',
            '@fax': '',
            '@billingZip': '',
            '@billingAddress': '',
            '@billingCity': '',
            '@billingCountry': '',
            '@billingState': '',
            '@vendor': '1',
            '@defaultEmail': 'test',
            '@defaultContactName': 'test'
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.