Search and replace specific tag value in XML file with sed command
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>
Related videos on Youtube
user3611640
Updated on September 18, 2022Comments
-
user3611640 over 1 year
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
-
Jeff Schaller over 5 yearsChoroba may not see this, since you deleted the post that they answered...
-
Kusalananda over 5 yearsIs that the complete XML document? It doesn't have a root node?
-
user3611640 over 5 yearsyes its complete XML Doc, also its having root node also, i just gave sample example.
-
user3611640 over 5 years@JeffSchaller...by mistake my old post got deleted...choroba has given me some solution i need some clarification on that.
-
user3611640 over 5 yearsthank 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
-
Kusalananda over 5 years@user3611640 Well, yes. It relies on having the
xmlstarlet
tool installed. On some Unices, it may be installed as justxml
, on others you will have to install it from the packaging system. It's available on Linux and BSD, at least. -
user3611640 over 5 years@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.
-
Kusalananda over 5 years@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 likesed
orawk
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. -
user3611640 over 5 years@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
-
Kusalananda over 4 yearsThis 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.