I am attempting to change values in a standalone-full.xml configuration file for a JBoss server. The issue I am running into is with the namespace. I have done several searches and tried several different scenarios, which I will provide. I know this has something to do with the namespace, because when I remove it the playbook works. My guess is that I am missing something simple and would greatly appreciate any assistance that can be given. I am rather light on xpath, which is probably a large portion of the problem.
Below I have sample code, and the different attempts to make this work.
sample.xml:
<?xml version='1.0' encoding='UTF-8'?>
<server xmlns="urn:jboss:domain:1.7">
<extensions>
    <!-- <extension module="org.jboss.as.clustering.infinispan"/>-->
    <extension module="org.jboss.as.cmp"/>
    <extension module="org.jboss.as.connector"/>
    <extension module="org.jboss.as.deployment-scanner"/>
    <extension module="org.jboss.as.ee"/>
    <extension module="org.jboss.as.ejb3"/>
    <extension module="org.jboss.as.jacorb"/>
    <extension module="org.jboss.as.jaxr"/>
    <extension module="org.jboss.as.jaxrs"/>
    <extension module="org.jboss.as.jdr"/>
    <extension module="org.jboss.as.jmx"/>
    <extension module="org.jboss.as.jpa"/>
    <extension module="org.jboss.as.jsf"/>
    <extension module="org.jboss.as.jsr77"/>
    <extension module="org.jboss.as.logging"/>
    <extension module="org.jboss.as.mail"/>
    <extension module="org.jboss.as.messaging"/>
    <extension module="org.jboss.as.naming"/>
    <extension module="org.jboss.as.pojo"/>
    <extension module="org.jboss.as.remoting"/>
    <extension module="org.jboss.as.sar"/>
    <extension module="org.jboss.as.security"/>
    <extension module="org.jboss.as.threads"/>
    <extension module="org.jboss.as.transactions"/>
    <extension module="org.jboss.as.web"/>
    <extension module="org.jboss.as.webservices"/>
    <extension module="org.jboss.as.weld"/>
</extensions>
<system-properties>
    <property name="app.datasource.connection-url" value="jdbc:oracle:thin:@(description=(address=(protocol=tcp)(host=mdatabase.example.com)(port=1521))(connect_data=(service_name=myservice)))"/>
    <property name="app.datasource.security.user-name" value="Myuser"/>
    <property name="app.datasource.security.password" value="mypassword"/>
</system-properties>
</server>
simpleplay.xml:
---
- hosts: all
  gather_facts: no
  connection: local
  tasks:
    - name: "Read XML"
      xml:
        path: sample.xml
        xpath: /server/system-properties/property[@name='app.datasource.security.user-name']
        attribute: value
        content: attribute
     register: my_val
- name: "Show me"
  debug:
    var: my_val
no-hosts:
localhost
First Attempt: ( Which verified to me that namespace was my issue.) In the sample.xml I changed:
<server xmlns="urn:jboss:domain:1.7">
to
<server>
to produce:
    PLAY [all] *******************************************************************************************************************************************************************************************************
    TASK [Read XML] **************************************************************************************************************************************************************************************************
    ok: [localhost]
    TASK [Show me] ***************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "my_val": {
        "actions": {
            "namespaces": {},
            "state": "present",
            "xpath": "/server/system-properties/property[@name='app.datasource.security.user-name']"
        },
        "changed": false,
        "count": 1,
        "failed": false,
        "matches": [
            {
                "property": {
                    "name": "app.datasource.security.user-name",
                    "value": "Myuser"
                }
            } 
        ],
        "msg": 1
        }
    }
    PLAY RECAP *******************************************************************************************************************************************************************************************************
    localhost                  : ok=2    changed=0    unreachable=0    failed=0
Added namespace to xml in play with the namespace added back to sample.xml:
---
- hosts: all
  gather_facts: no
  connection: local
  tasks:
    - name: "Read XML"
      xml:
        path: sample.xml
        xpath: /x:server/system-properties/property[@name='app.datasource.security.user-name']
        namespaces:
          x: "urn:jboss:domain:1.7"
        attribute: value
        content: attribute
     register: my_val
which produces:
PLAY [all] *******************************************************************************************************************************************************************************************************
TASK [Read XML] **************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Xpath /x:server/system-properties/property[@name='app.datasource.security.user-name'] does not reference a node!"}
to retry, use: --limit @/home/ec2-user/work/xpathtest/simpleplay.retry
PLAY RECAP *******************************************************************************************************************************************************************************************************
localhost                  : ok=0    changed=0    unreachable=0    failed=1
Several xpaths that I have tried:
/x:server/x:system-properties/x:property[@x:name='app.datasource.security.user-name']
/server[namespace-uri()='urn:jboss:domain:1.7']/system-properties/property[@name='app.datasource.security.user-name']
/*[local-name()=server]/system-properties/property[@name='app.datasource.security.user-name']
All producing the above result as well.
My fear is I don't understand namespace well enough to see what I am doing wrong. Any help would be appreciated.
The issue is with namespaces. All of the elements are bound to the namespace urn:jboss:domain:1.7. It is a little difficult to see that, since there is no namespace prefix. All of the elements are bound to that namespace, but unless a namespace prefix is used for an attribute, it will not be.
So, your XPath: /x:server/x:system-properties/x:property[@x:name='app.datasource.security.user-name'] should be:
/x:server/x:system-properties/x:property[@name='app.datasource.security.user-name']
For the XPath: /server[namespace-uri()='urn:jboss:domain:1.7']/system-properties/property[@name='app.datasource.security.user-name'] you would need to match generically on any element * and then use a predicate to restrict by the local-name() and can also use the namespace-uri() as criteria:
/*[local-name() = 'server' and namespace-uri() = 'urn:jboss:domain:1.7']/*[local-name() = 'system-properties']/*[local-name() = 'property' and @name='app.datasource.security.user-name']
For the XPath /*[local-name()=server]/system-properties/property[@name='app.datasource.security.user-name'], you did not have server in quotes. It was attempting to compare the local-name() to a child element server, which does not exist. Similarly, you would need to use a predicate to match the local-name() for the descendants:
/*[local-name()='server']/*[local-name() = 'system-properties']/*[local-name() = 'property' and @name='app.datasource.security.user-name']
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With