user3777747 user3777747 - 1 month ago 6
Bash Question

How to update specific XML tag values using a shell script?

The following is a part of a XML where I want to change

username
and
password
with any desired values.

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://x.x.x.x:3306/app
</value>
</property>
<property name="username">
<value>user1</value>
</property>
<property name="password">
<value>pass1</value>
</property>
</bean>


The values (
<value>
tags) of
username
and
password
properties may contain anything, e.g.
user1
,
pass1
,
user2
,
pass2
, etc.
How do I update these strings with different values in a shell?

Answer

The following xmlstarlet command updates the password value in source.xml file according to XPath expression:

xmlstarlet ed --inplace \
  -u "//bean[@id='dataSource']//property[@name='password']/value" \
  -v 'new_pass' source.xml

Note, the double slash (//) in the XPath expression selects nodes in the document from the current node that match the selection no matter where they are (read this, for example). I've included it into the expression, because I suspect that the XML you mentioned in the question has a number of parent nodes.

If there is a namespace declared, you should specify it explicitly. For example, if the root element is declared as <beans xmlns="http://www.springframework.org/schema/beans">, then you should specify the namespace using -N global option:

xmlstarlet ed --inplace \
  -N x=http://www.springframework.org/schema/beans \
  -u "//x:bean//x:property[@name='password']/x:value" \
  -v 'new_pass' source.xml

This is just a sample command that will work with XML you posted in the question. If you have different structure, adjust the XPath expression accordingly.

source.xml (before running the command)

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
    <value>jdbc:mysql://x.x.x.x:3306/app
    </value>
  </property>
  <property name="username">
    <value>user1</value>
  </property>
  <property name="password">
    <value>pass1</value>
  </property>
</bean>

source.xml (after running the command)

<?xml version="1.0"?>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
  <property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
    <value>jdbc:mysql://x.x.x.x:3306/app
    </value>
  </property>
  <property name="username">
    <value>user1</value>
  </property>
  <property name="password">
    <value>new_pass</value>
  </property>
</bean>
Comments