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

  • @choroba can you please let me know how we can achieve this using bash shell script. – user3611640 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. – user3611640 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. – user3611640 Dec 10 '18 at 13:48
2

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>
  • 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 – user3611640 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. – user3611640 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 – user3611640 Dec 11 '18 at 9:16
-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
  • 1
    This may work for the file in question, but relies on the fact that the nodes occurs on separate and consecutive lines. If the sed syntax was corrected (the expressions contains far too many slashes) it would also change the value 33 to 325. – Kusalananda Dec 11 '18 at 9:24

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.