How to Parse the XML response of a URI in ansible

ansible uri cookie
ansible uri body template
ansible to_datetime
ansible uri retry
ansible uri localhost
ansible uri proxy
default ansible
ansible password_hash

There is a code which call the web services of an application.

 - 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

The sample response is

"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>"

I want to access the list response in my next block of code. Like i need just the value of "customerId". How this can be achieved using anisble

There is no XML support in Ansible out of the box. You can use regex filters to make some simple searches in your XML data. In your example:

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

Will search for customerId=\"<number>\" strings and return a list of numbers in quotes.

Update: fully working example:

- 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+)\"') }}"

I use ansible 2.1.1.0.

Getting string from an XML URL response, I have a URL that I call with a GET, and that returns an XML response. I'd like to parse that response (I could use grep), but I'm struggling to get the response TASK [ansible-ohp-win-installer : Output current env details]  SUMMARY This PR add support for parsing XML payload useful when automating XML, XHTML or SOAP payload. ISSUE TYPE Feature Pull Request COMPONENT NAME uri ADDITIONAL INFORMATION [dwieers@localhost

This is similar to sebaszw's answer, however doesn't require the xml response to be written to a file, instead storing it in a variable.

- 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 

uri – Interacts with webservices, The body of the http request/response to the web service. You must either add a leading zero so that Ansible's YAML parser knows it is an octal number (like  The body of the http request/response to the web service. If body_format is set to 'json' it will take an already formatted JSON string or convert a data structure into JSON.

From Ansible 2.4 you can do this:

- 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

xml – Manage bits and pieces of XML files or strings, This parameter requires xpath to be set. namespaces. dictionary. The namespace prefix:uri mapping for the XPath expression. Needs  no ←. yes. Add additional child-element (s) before the first selected element for a given xpath. Child elements must be given in a list and each item may be either a string (eg. children=ansible to add an empty <ansible/> child element), or a hash where the key is an element name and the value is the element value.

Its worth looking at ansible-xml for this. It's not part of Ansible but its a super useful module for parsing xml, it uses the lxml Python library under the hood.

xml, xml; yaml. Type of input for add_children and set_children . namespaces. no. The namespace prefix:uri mapping for the XPath expression. Giving Ansible a number without following one of these rules will end up with a decimal number which will have unexpected results. As of Ansible 1.8, the mode may be specified as a symbolic mode (for example, u+rwx or u=rw,g=r,o=r ). As of Ansible 2.6, the mode may also be the special string preserve.

I just added XML parsing support in the uri module because I needed it too. https://github.com/ansible/ansible/pull/53045

Just like the JSON support, it will return an 'xml' key with a dictionary consisting of the XML content for the convenience of accessing the data in the payload.

Your example would look like this:

 - 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']

The output in customerId.xml would be:

{
    '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'
        }
    }
}

xml module: Reading attribute value into ansible variable is , From @ssbarnea on April 15, 2016 11:54 ISSUE TYPE Documentation Report COMPONENT NAME xml ANSIBLE VERSION v2.4 SUMMARY  Does anyone have experience with the uri module in Ansible? I'm trying to convert the following command into an Ansible playbook: Testing the Web SDK Configuration curl -v -X POST -H "

SOAP XML : ansible, I have read the ansible xml module docs and played around with "xmlstring" value element's attribute values xml: xmlstring: "{{ xmlresponse.content }}" content: i read some where on stackoverflow that XML parsing was now in the core URI  The parse_xml filter will load the spec file and pass the command output through formatted as JSON. The spec file should be valid formatted YAML. It defines how to parse the XML output and return JSON data. Below is an example of a valid spec file that will parse the output from the show vlan | display xml command.

Ansible variable assignment using URI & XML modules, Here is what the response looks like: TASK [debug var=sysinfo] I just added XML parsing support in the uri module because I needed it too. I have an Ansible task that makes a URI request to a website to get a JSON response. I want Ansible to do something if the nested JSON variable is defined, and something else if it isn't.

How to check the JSON response from a uri request with Ansible , name: Example of JSON body parsing with uri module connection: local gather_facts: true hosts: localhost tasks: - name: Example of JSON body parsing with uri  Ways to provide body payload in Ansible’s URI module [Update] Talin to a REST API requires to provide some information, usually in the form of JSON payload. Ansible offers various ways to do that in the URI module in playbooks.

Comments
  • I had this same problem and instead of getting any value i am getting what is mentioned in msg. Like for this case it is "msg": "{{customerId.content | regex_findall(\"customerId=\\\"(\\d+)\\\"\")}}" . It is the result of this particular task.
  • I've updated the answer with fully working example, please inspect it.
  • FYI: documentation docs.ansible.com/ansible/2.4/xml_module.html