Search code examples
xmlbashxmlstarlet

XMLStarlet ed -s gives usage error on 1.3.1, works on 1.6.1 -- what changed?


Im using xmlstarlet for editing a few xml config files. The default file looks like this:

<configuration>
  <property>
    <name></name>
    <value></value>
  </property>
  <property>
    <name></name>
    <value></value>
  </property>
</configuration>

I am adding a couple more <property> subnodes. like this:

    sudo xmlstarlet ed -L \
      -s '//configuration' -t elem -n "property" \
      -s '//configuration/property[last()]' -t elem -n "name" -v "test-1" \
      -s '//configuration/property[last()]' -t elem -n "value" -v "00001" \
      -s '//configuration' -t elem -n "property" \
      -s '//configuration/property[last()]' -t elem -n "name" -v "test-2" \
      -s '//configuration/property[last()]' -t elem -n "value" -v "00002" \
      /etc/path/to/file.xml

I tested this locally, with XMLStarlet 1.6.1, and it worked great and exactly how I wanted it to. The result looks like this:

<configuration>
  <property>
    <name></name>
    <value></value>
  </property>
  <property>
    <name></name>
    <value></value>
  </property>
  <property>
    <name>test-1</name>
    <value>00001</value>
  </property>
  <property>
    <name>test-2</name>
    <value>00002</value>
  </property>
</configuration>

However when I put this in a shell script and then tried running it on my remote instance (with XMLStarlet 1.3.1), it keeps printing out the help text for the package like when you just type xmlstarlet in the terminal. I have no idea what could be causing this

[remote-machine ~]$ xmlstarlet
XMLStarlet Toolkit: Command line utilities for XML
Usage: xmlstarlet [<options>] <command> [<cmd-options>]
where <command> is one of:
  ed    (or edit)      - Edit/Update XML document(s)
  sel   (or select)    - Select data or query XML document(s) (XPATH, etc)
  tr    (or transform) - Transform XML document(s) using XSLT
  val   (or validate)  - Validate XML document(s) (well-formed/DTD/XSD/RelaxNG)
  fo    (or format)    - Format XML document(s)
  el    (or elements)  - Display element structure of XML document
  c14n  (or canonic)   - XML canonicalization
  ls    (or list)      - List directory as XML
  esc   (or escape)    - Escape special XML characters
  unesc (or unescape)  - Unescape special XML characters
  pyx   (or xmln)      - Convert XML into PYX format (based on ESIS - ISO 8879)
  p2x   (or depyx)     - Convert PYX into XML
<options> are:
  --version            - show version
  --help               - show help
Wherever file name mentioned in command help it is assumed
that URL can be used instead as well.

Type: xmlstarlet <command> --help <ENTER> for command help

XMLStarlet is a command line toolkit to query/edit/check/transform
XML documents (for more information see http://xmlstar.sourceforge.net/)

xmlstarlet ed -s is valid in both of these versions; what changed, to make my script version-specific?


Solution

  • In XMLStarlet 1.3.1 (which you have on your remote system), the -v argument to xmlstarlet ed -s is mandatory.

    Thus, you need to add -v '' when adding the property elements.

    sudo xmlstarlet ed -L \
      -s '//configuration' -t elem -n "property" -v '' \
      -s '//configuration/property[last()]' -t elem -n "name" -v "test-1" \
      -s '//configuration/property[last()]' -t elem -n "value" -v "00001" \
      -s '//configuration' -t elem -n "property" -v '' \
      -s '//configuration/property[last()]' -t elem -n "name" -v "test-2" \
      -s '//configuration/property[last()]' -t elem -n "value" -v "00002" \
      /etc/path/to/file.xml