0

I have a task where by I have to manipulate an XML file through a bash shell script.

Here are the steps:

  • Query XML file for a value.
  • Replace the value of a different element with the new value.

Here is the sample xml:

<context-param>
    <param-name>com.sun.faces.sendPoweredByHeader</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <param-name>com.sun.faces.numberOfViewsInSession</param-name>
    <param-value>25</param-value>
  </context-param>
  <context-param>
    <param-name>testing</param-name>
    <param-value>25</param-value>
  </context-param>

I need to update the parm value of <param-value>25</param-value> to <param-value>3</param-value> using a shell script.

Any idea what will be the SED command to update only param value of param name(<param-name>com.sun.faces.numberOfViewsInSession</param-name>)?

i tried with below command,

sed -i 's/<param-value>25<\/param-value>/<param-value>3<\/param-value>/' test.xml

but this command will update all the param-values. i need to update only for com.sun.faces.numberOfViewsInSession

5
  • @choroba can you please let me know how we can achieve this using bash shell script. Dec 10 '18 at 13:34
  • 1
    Choroba may not see this, since you deleted the post that they answered...
    – Jeff Schaller
    Dec 10 '18 at 13:42
  • Is that the complete XML document? It doesn't have a root node?
    – Kusalananda
    Dec 10 '18 at 13:42
  • yes its complete XML Doc, also its having root node also, i just gave sample example. Dec 10 '18 at 13:47
  • @JeffSchaller...by mistake my old post got deleted...choroba has given me some solution i need some clarification on that. Dec 10 '18 at 13:48
3

Using XMLStarlet, and assuming that the document has a root node:

xmlstarlet ed \
    -u '//context-param[param-name = "com.sun.faces.numberOfViewsInSession"]/param-value[. = 25]' \
    -v 3 file.xml

This selects the correct param-value node (the one that has a value of 25 (drop the [. = 25] bit if the old value is unimportant) and is a child node of the context-param node whose param-name child node has the value com.sun.faces.numberOfViewsInSession), and changes its value to 3.

The resulting document will be (with a fake root node inserted):

<?xml version="1.0"?>
<root>
  <context-param>
    <param-name>com.sun.faces.sendPoweredByHeader</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <param-name>com.sun.faces.numberOfViewsInSession</param-name>
    <param-value>3</param-value>
  </context-param>
  <context-param>
    <param-name>testing</param-name>
    <param-value>25</param-value>
  </context-param>
</root>
5
  • thank you so much for the solution, sorry but i am new to shell/bash script...i tried your command, i am getting below error: xmlstarlet: command not found Dec 10 '18 at 13:57
  • 1
    @user3611640 Well, yes. It relies on having the xmlstarlet tool installed. On some Unices, it may be installed as just xml, on others you will have to install it from the packaging system. It's available on Linux and BSD, at least.
    – Kusalananda
    Dec 10 '18 at 14:00
  • @kusalananda....i am not sure i will be able to install xmlstarlet at client box, any other approach is there to achieve this..like using xml or sed command. Dec 10 '18 at 14:05
  • 4
    @user3611640 I'm not going to give you a sed answer. Structured document formats like XML (or JSON or even some forms of CSV) require parsing by a real parser, not a line-oriented text tool like sed or awk or any of the other standard Unix text manipulation tools. You could also parse the XML in Python or Perl with some XML module, obviously.
    – Kusalananda
    Dec 10 '18 at 14:08
  • @kusalananda...i got the solution using sed command, also its working as expected. sed -i '/<param-name>com.sun.faces.numberOfViewsInSession<\/param-name>/{n;s/<param-value>3<\/param-value>/<param-value>25<\/param-value>/}' web.xml Dec 11 '18 at 9:16
-1
sed -i 's#<param-value>25</param-value>#<param-value>3</param-value>#' test.xml
1
  • 1
    This would possibly change irrelevant lines in the document. In the example given, two lines would be changed instead of the intended single line. In fact, this is exactly equivalent to the command that the user in the question tried for themselves.
    – Kusalananda
    Nov 23 '19 at 11:10
-2

using below sed command, we can update the specific tag value:-

sed -i '/<param-name>com.sun.faces.numberOfViewsInSession<\/param-name>/{n;s/<param-value>3<\/param-value>/<param-value>25<\/param-value>/}' test.xml
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.