2

I have a XML from which I need to parse a value using Ansible.
Below is the XML:

<?xml version="1.0" encoding="utf-8"?>
<Activity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://example.com/2005/06/StandardHeader/" xmlns="http://example.com/xsd/frm/v1/Activity/ManageInternalCustomerChangeRequest">
  <ActivityDetails>
    <activityId>basdsds5-21aa-4ec4-b453-5f08af0fc612</activityId>
    <activityType>ServiceIdRecordUpdate</activityType>
    <activityStartDate>%DateTime%</activityStartDate>
    <listOfActivityAttribute>
      <activityAttribute>
        <name>CustomerId</name>
        <value>%CustomerId%</value>
      </activityAttribute>
      <activityAttribute>
        <name>AssetInstanceId</name>
        <value>%AssetInstanceId%</value>
      </activityAttribute>
      <activityAttribute>
        <name>ServiceId</name>
        <value>%ServiceId%</value>
      </activityAttribute>
      <activityAttribute>
        <name>SupplierServiceId</name>
        <value>%SupplierServiceId%</value>
      </activityAttribute>
    </listOfActivityAttribute>
  </ActivityDetails>
</Activity>

I am able to parse and extract the value of the node activityId i.e basdsds5-21aa-4ec4-b453-5f08af0fc612 using this Ansible task

- name: Step-3:Read an element's attribute values
  xml:      
    path: /tmp/test.xml
    xpath: /x:Activity/x:ActivityDetails/x:activityId
    content: text
    namespaces:
      x: "http://example.com/xsd/frm/v1/Activity/ManageInternalCustomerChangeRequest"
  register: xmlresp

Which gives me the value

{"ansible_facts": {"Value": "basdsds5-21aa-4ec4-b453-5f08af0fc612"}, "changed": false}

However I am unable to parse or extract the value for CustomerId using the below. I have tried prefixing the namespace across the XPath, without any more success.

- name: Step-4:Read Customer ID from XML
  xml:
    path: /tmp/test.xml
    xpath: /x:Activity/ActivityDetails/listOfActivityAttribute/activityAttribute[name='CustomerId']/value
    content: text
    namespaces:
      x: "http://example.com/xsd/frm/v1/Activity/ManageInternalCustomerChangeRequest"
  register: xmlresp1

It fails with the error

FAILED! => {"changed": false, "msg": "Xpath /x:Activity/x:ActivityDetails/x:listOfActivityAttribute/x:activityAttribute[name='CustomerId'] does not reference a node!"}

I need to extract the value %CustomerId%, using Ansible.

1 Answer 1

3

You really have to add the namespace on everything, which include the name node: x:name!

So, your XPath end up being something like:

xpath: >-
  /x:Activity
  /x:ActivityDetails
  /x:listOfActivityAttribute
  /x:activityAttribute[x:name='CustomerId']
  /x:value

Given the two tasks:

- xml:
    path: test.xml
    xpath: >-
      /x:Activity
      /x:ActivityDetails
      /x:listOfActivityAttribute
      /x:activityAttribute[x:name='CustomerId']
      /x:value
    content: text
    namespaces:
      x: "{{ _x }}"
  register: xmlresp
  vars:
    _x: http://example.com/xsd/frm/v1/Activity/ManageInternalCustomerChangeRequest

- debug:
    var: xmlresp.matches.0['{' ~ _x ~  '}value']
  vars:
    _x: http://example.com/xsd/frm/v1/Activity/ManageInternalCustomerChangeRequest

The debug ends up giving:

ok: [localhost] => 
  xmlresp.matches.0['{' ~ _x ~  '}value']: '%CustomerId%'

Side note: to DRY this code, you can define the _x variable representing the namespace on an upper level, e.g. at the playbook or inventory level.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.