1

Hi I have an xml file. I want to add the following tags when I see the tag. For example

I want to add

<Context 
allowLinking="false"
privileged="false"
useHttpOnly="true"
xmlValidation="false">
</Context>

The file looks like this

<Context>
</Context>

After adding it should like this

<Context allowLinking="false"
privileged="false"
useHttpOnly="true"
xmlValidation="false">
</Context>

I used the following sed command but I am not able to add the parameters inside the tag as shown above

I tried the following sed

grep 'allowLinking' /bao/tomcat/conf/context.xml
if [ $? -ne 0 ]
then    
    sed -i '/<Context .*?>/i allowLinking="false" \n privileged="false" \n useHttpOnly="true" \n xmlValidation="false"/' /tmp/context.xml
fi

Could you please let me know how to add the contents.

Thanks Dinesh

1 Answers1

0

You might like to try:

sed -i 's/<Context *>/<Content allowLinking="false" \n privileged="false" \n useHttpOnly="true" \n xmlValidation="false">/' /tmp/context.xml

This uses the s command rather than your i command, and it replaces your space.*? in the search with just space*.

The .*? might be useful if you wanted to replace existing attributes, but it would only work here if they were all in one line, and in any case you would need something like [^>]* to avoid swallowing the closing >.

Finally, a cleaner, more generic way of writing this is to use shell variables (tested with bash):

ATTRIB='allowLinking="false" \n privileged="false" \n useHttpOnly="true" \n xmlValidation="false"'
TAG='Context'
sed -i "s/<${TAG} *>/<${TAG} ${ATTRIB}>/" /tmp/context.xml

Caution: As Michael Kay notes in his comment:

[This] only worked because you were lucky: there were no special characters like ampersands in your data.

With the Linux sed, the special characters to be wary about are [\^$.*&, and -] following a [. sed -E adds ?+|{}(), see here. Other sed's might include more.

Also, as written, the example cannot include single quotes ' or forward-slashes /, unless they are escaped by a backslash \. Note the \n is used to introduce line breaks; the use of backslash is ok here.

Finally, as Micheal Kay points out, this is not a job for sed, it's a job for XSLT. And of course, everyone needs to be aware of this famous answer from 2009: RegEx match open tags except XHTML self-contained tags.

Joseph Quinsey
  • 9,553
  • 10
  • 54
  • 77
  • It only worked because you were lucky: there were no special characters like ampersands in your data. (as a matter of interest, before saying it worked, how many test cases did you run?) Don't use this in production, or you'll soon find one of the consumers of your "XML" asking on StackOverflow how to deal with ill-formed "XML" data files. – Michael Kay Jan 24 '19 at 14:50