0

I'm trying to figure out how to insert a text in an xml file with sed command. I started to try some basic commands with sed :

sed -i -e ' <property name="prop1" ref="ANOTHER_BEAN" /> ' my_config_file.xml  

it's adding this line but not in the position that I want

The problem for my specific case is that the text should be add to a certain position (certain bean as it's a java config file)

Example

 <bean id="BEAN_ID_1"
    class="com.toto.BeanClass1"
    scope="prototype">
    <property name="prop1" ref="ANOTHER_BEAN_1" />
    <property name="prop2" ref="BEAN1" />
 </bean>

<bean id="BEAN_ID_2"
    class="com.toto.BeanClass2"
    scope="prototype">
    <property name="prop_1" ref="ANOTHER_BEAN_2" />
    <property name="prop_2" ref="BEAN2" />
 </bean>

I want to add this property to the bean named 'BEAN_ID_1' before the enclosing tag

 <property name="property" ref="ANOTHER_BEANXXX" />

so the output will be :

 <bean id="BEAN_ID_1"
    class="com.toto.BeanClass1"
    scope="prototype">
    <property name="prop1" ref="ANOTHER_BEAN_1" />
    <property name="prop2" ref="BEAN1" />
    <property name="property" ref="ANOTHER_BEANXXX" />
 </bean>

<bean id="BEAN_ID_2"
    class="com.toto.BeanClass2"
    scope="prototype">
    <property name="prop_1" ref="ANOTHER_BEAN_2" />
    <property name="prop_2" ref="BEAN2" />
 </bean> 

PS: I can't rely on line number since in production I have no Idea how is the file

Can anybody help me on this ? Thanks a lot

2 Answers 2

2

Using an XML parser/editor to edit your XML is always a safer approach than trying to fudge it with sed.

I've fixed up your XML sample by wrapping it all in <beans>...</beans> so that it's valid XML. And here is a solution using xmlstarlet:

xmlstarlet edit --subnode '//bean[@id="BEAN_ID_1"]' -t elem -n property --var this '$prev' --insert '$this' -t attr -n name -v property --insert '$this' -t attr -n ref -v 'ANOTHER_BEANXXX' configFile

Output

<?xml version="1.0"?>
<beans>
  <bean id="BEAN_ID_1" class="com.toto.BeanClass1" scope="prototype">
    <property name="prop1" ref="ANOTHER_BEAN_1"/>
    <property name="prop2" ref="BEAN1"/>
    <property name="property" ref="ANOTHER_BEANXXX"/>
  </bean>
  <bean id="BEAN_ID_2" class="com.toto.BeanClass2" scope="prototype">
    <property name="prop_1" ref="ANOTHER_BEAN_2"/>
    <property name="prop_2" ref="BEAN2"/>
  </bean>
</beans>

Explanation of the xmlstarlet line:

# Edit the XML, writing the result to stdout
xmlstarlet edit

# Create a subnode called "property" of "//bean" having an attribute id="BEAN_ID_1"
--subnode '//bean[@id="BEAN_ID_1"]' -t elem -n property

# Identify this new element as "this"
--var this '$prev'

# Insert an attribute called "name" with a value "property" into the new element
--insert '$this' -t attr -n name -v property

# Insert an attributed called "ref" with a value "ANOTHER_BEANXXX" into the new element
--insert '$this' -t attr -n ref -v 'ANOTHER_BEANXXX'

# XML source file
configFile
1
1

You might consider using an xml parser for xml; would be more robust.

But maybe something like this?

sed -i '/<bean id="BEAN_ID_1"/,/<\/bean>/ s/<\/bean>/   <property name="property" ref="ANOTHER_BEANXXX" \/>\n<\/bean>/' my_config_file.xml

This means within the range starting with <bean id="BEAN_ID_1" and ending with </bean>, insert the line <property name="property" ref="ANOTHER_BEANXXX" /> right before </bean>.

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.