Home > Software design >  Ansible replace xml element value on lines with a specific attribute
Ansible replace xml element value on lines with a specific attribute

Time:10-08

I have the below content from xml in which I am trying to parameterize value="" for lines with name="database".

for example the current value which is value="test.abc.com" in line 1 should be replaced with a different value as value="new_test.abc.com".

Note: There are multiple such lines in the xml file, the one below is just a part of it.

<?xml version="1.0" encoding= "UTF-8"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:resources.j2c="http://www.ibm.com/websphere/appserver/schemas/5.0/resources.j2c.xmi">
<resources.jdbc:JDBCProvider xmi:id="JDBCProvider_1" name="Oracle JDBC Driver (XA)" description="JDBC provider" providerType="Oracle JDBC Driver (XA)" isolatedClassloader="false" implementationClassName="oracle.jdbc.xa.client.OracleXADataSource" xa="false">
    <classpath>${ORACLE_JDBC_DRIVER_PATH}/jdbc/Lib/gidbc7.jar</classpath>
    <classpath>$(ORACLE_JDBC_DRIVER_PATH}/jdbc/Lib/oidbc:.jar</classpath>
    <classpath>${ORACLE_JDBC_DRIVER_PATH}/rdbms/1L1b/xdb6.jar</classpath>
    <factories xmi:type="resources. jdbc: DataSource" xmi:id="DataSource_1" name="DWLConfig" JndiName="jdbc/DWLConfig" description="XA Datasource for">
    <propertySet xmi:id="J2EEResourcePropertySet_1">
        <resourceProperties xmi:id="J2EEResourceProperty_1" name="databaseName" type="java.lang.String" value="test.abc.com" required="true"/>
        <resourceProperties xmi:id="J2EEResourceProperty_2" name="driverType" type="java.Lang.String" value="4" description="" required="true"/>
        <resourceProperties xmi:id="J2EEResourceProperty_3" name="serverName" type="java.lang.String" value="test-scan.abc.com" required="true"/>
        <resourceProperties xmi:id="J2EEResourceProperty_4" name="portNumber" type="java.lang.String" value="1521" description="" required="true"/>
        <resourceProperties xmi:id="J2EEResourceProperty_5" name="webSphereDefaultIsolationLevel" type="java.lang.Integer" value="2"/>
        <resourceProperties xmi:id="J2EEResourceProperty_6" name= "downgradeHoldCursorsUnderXa" type="java.lang.Boolean" value="true"/>
        <resourceProperties xmi:id="J2EEResourceProperty_7" name="UseRRASetEquals" type="java.lang.Boolean" value="true" description="Set for pME"/>
        <resourceProperties xmi:id="J2EEResourceProperty_8" name="currentSchema" type="java.lang.String" value="INITIATE" description=""/>
        <resourceProperties xmi:id="J2EEResourceProperty_9" name="URL" type="java.lang.String"/>
    </propertySet>
    <connectionPool xmi:id="ConnectionPool_1" connectionTimeout="180" maxConnections="85" minConnections="I" reapTime="180" unusedTimeout="1800"/>
    <mapping xmi:id="MappingModule_1" mappingConfigAlias="" authDataAlias="Node01/User-config"/>
    </factories>
</resources.jdbc:JDBCProvider>
</xmi:XMI>

I have tried using:

- name: xml update
  xml:
    path: "{{ item }}"
    xpath: /xmi:XMI/resources.jdbc:JDBCProvider/factories/propertySet/resourceProperties[@name="database"]
    attribute: value
    value: new_test.abc.com
    state: present
  with_items:
    - file1.xml
    - file2.xml

But it throws the following error:

XPathEvalError: Undefined namespace prefix

CodePudding user response:

The "Undefined namespace prefix" means you're using a namespace prefix in your XML, but you haven't told Ansible what XML namespace that corresponds to. If you see an element name like <xmi:XMI>, that leading xmi: prefix is just a pointer to the actual namespace, which in this document is http://www.omg.org/XMI.

So in your xml task, you need to provide the namespaces key to map prefixes to actual namespaces:

- name: xml update
  xml:
    path: "{{ item }}"
    xpath: /xmi:XMI/resources.jdbc:JDBCProvider/factories/propertySet/resourceProperties[@name="database"]
    attribute: value
    value: new_test.abc.com
    state: present
    namespaces:
      xmi: http://www.omg.org/XMI
      resources.jdbc: ...something...
  with_items:
    - file1.xml
    - file2.xml

The XML you've posted is invalid; it uses the resources.jdbc namespace prefix but doesn't actually define it anywhere. You'll need to fix that (and add the appropriate entry to the namespaces dictionary in your task) in order for your playbook to work.

  • Related