How to insert elements with attributes to an XML file using XmlStarlet?

Gergő picture Gergő · Sep 29, 2013 · Viewed 7.4k times · Source

Source XML

<xml>
    <block>
        <el name="a">92346</el>
        <el name="b">lorem</el>
    </block>
    <block>
        <el name="a">89753</el>
        <el name="b">ipsum</el>
    </block>
</xml>

Object

I would like to insert an <el name="c">0</el> element in every <block> with a Linux shell script:

<xml>
    <block>
        <el name="a">92346</el>
        <el name="b">lorem</el>
        <el name="c">0</el>
    </block>
    <block>
        <el name="a">89753</el>
        <el name="b">ipsum</el>
        <el name="c">0</el>
    </block>
</xml>

I can append the elements using XmlStarlet:

xmlstarlet ed -a '/xml/block/el[@name="b"]' \
              --type 'elem' -n 'el' -v 0

Questions

  1. What is the XPath expression that selects every <el> element which doesn't have a name attribute?
  2. Can I append the elements and insert the attributes with a single xml ed command?

Answer

Gergő picture Gergő · Sep 29, 2013

Answers

  1. /xml/block/el[not(@name)]
  2. As stated in an other answer:

You can't insert an element with an attribute directly but since every edit operation is performed in sequence, you can insert an element and then add an attribute.

The command

xmlstarlet ed -a '/xml/block/el[@name="b"]' \
              -t 'elem' -n 'el' -v 0 \
              -i '/xml/block/el[not(@name)]' \
              -t 'attr' -n 'name' -v 'c'