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