0

I am using this XML file: https://github.com/apache/ranger/blob/master/ugsync/src/test/resources/ranger-ugsync-site.xml

Now, I have to update the value of the following property to false.

<property>
  <name>ranger.usersync.group.usermapsyncenabled</name>
  <value>true</value>
</property>

To update the value of property in the XML to false, I am using the below command in the bash script to get the updates done.

tag1=<name>ranger.usersync.group.usermapsyncenabled</name>
file=xml_file.xml
temporary=temp.xml

grep -A1 $tag1 $file | grep -v $tag1 | sed -e "s/^.*<value>/<value/" | sed -e "s/<value>true<\/value>/<value>false<\/value>/g" $file > $temporary

Problem: The script is updating all the other attributes in the file with value true to false. I just need to update the value of this attribute and not others. Input/help is appreciated. Thanks!

2
  • Hmm. I'm tempted to call this duplicative of parsing xml and replacing specific tags shell script, which includes an XMLLint approach in the answers as well. Ideally, would like to find a duplicative question with a Python-wrapped-in-a-shell-function answer, since that's likely to be useful to folks who for whatever reason can't install XMLStarlet and who don't have a new enough XMLLint. Commented Feb 25, 2018 at 19:11
  • ...to be clear, by the way -- XML-aware answers are strongly preferred for this class of question because standard text-based tools simply don't, and can't, understand XML. You can't teach grep and sed to ignore XML comments and CDATA sections, and to read xmlns tags to figure out the current namespace, and to read DTDs and understand any macros they contain, etc. Commented Feb 25, 2018 at 19:14

1 Answer 1

4

Using XMLStarlet:

xmlstarlet ed \
  -u "//property[name='ranger.usersync.group.usermapsyncenabled']/value" \
  -v false \
  <in.xml >out.xml

The XPath expression used to determine what to change ensures that we only modify a value that is under a property with the appropriate name.

Sign up to request clarification or add additional context in comments.

7 Comments

the problem using XMLStarlet is that it disrupts the formatting and also changes the <value></value> line to <value/>. Hope that is going to be fine? I am planning to use this script in a Dockerfile so that it can do the updates when I run the dockerfile and so I was looking more for sed or grep steps. Sorry, kinda new to scripting and hence looking for the right answers.
@yguw, the values are semantically equivalent to each other, which is to say that any compliant XML parser will treat both documents as equal except for the desired change.
See my comments on the question speaking to why sed and grep are not the right answer for any kind of XML-manipulation task.
Also, note the -S and -P arguments to xmlstarlet ed to preserve original whitespace.
(BTW, if you want to prevent spurious changes to the text of your XML documents when modifying their content, consider keeping them in canonicalized form; see the XML C14N standard -- any XML processor that supports the standard will be able to take a canonicalized document as input and emit byte-for-byte-identical output except for the actual desired change (when told to write canonicalized output).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.