Add a document with two main nodes to an existing document using xmlstarlet

I have a existing XML that looks like this:

<data>    <item>       <A>value1</A>       <B>value1<B>    </item>    <item>       <A>value2</A>       <B>value2<B>    </item> </data> 

To this xml file I want to add a second one:

<data>    <item>       <A>value2</A>       <B>value2<B>    </item>    <item>       <A>value3</A>       <B>value3<B>    </item> </data> 

The resulting file should look like this:

<data>    <item>       <A>value1</A>       <B>value1<B>    </item>    <item>       <A>value2</A>       <B>value2<B>    </item>    <item>       <A>value3</A>       <B>value3<B>    </item>    <item>       <A>value4</A>       <B>value4<B>    </item> </data> 

I use the followig command

xmlstarlet edit --subnode '//data' --type text -n '' --value "$(xmlstarlet select --omit-decl -t --copy-of '//data/item' filename_to_add.xml | xmlstarlet unescape | xmlstarlet format --nsclean)" filename.xml 

I get the error

Extra content at the end of the document     </item><item> 

I guess that is because the xml document in my select query has two main nodes item and that is no valid xml. I understand that, however, it’s just a step within the process of adding it. Unfortunately, it doesn’t allow me to add the subnode. What can I do?

Add Comment
1 Answer(s)

You have your closing bracket at the wrong place. Try this command:

xmlstarlet edit --subnode '//data' --type text -n '' --value "$(xmlstarlet select --omit-decl -t --copy-of '//data/item' filename_to_add.xml.xml)" filename.xml | xmlstarlet unescape | xmlstarlet format --nsclean 

In the given example you could change both //data to /data simplifying the expressions.
Its output is

<?xml version="1.0"?> <data>   <item>     <A>value1</A>     <B>value1</B>   </item>   <item>     <A>value2</A>     <B>value2</B>   </item>   <item>     <A>value2</A>     <B>value2</B>   </item>   <item>     <A>value3</A>     <B>value3</B>   </item> </data> 

This is the desired output (your input files and the desired output in your question are out-of-sync).

Answered on July 17, 2020.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.