XML with XmlStarlet

Introduction

XmlStarlet is a cross-platform, command-line utility writtent by Mikhail Grushinskiy to read/modifiy XML files. It requires first learning XPath (and XSLT since XmlStarlet relies on its logic). Strangely enough, it looks like it can only read from a local file, not fetch a page from a remote website ("failed to load external entity") — which can be done with eg. wget or curl.

The main commands are:

Studying the structure

To see the whole file: xml el table.xml

To include attributes: xml el -a table.xml

To include attributes and their values: xml el -v table.xml

To see just the structure: xml el -u table.xml

Querying

The plain command is: xml sel -t <options>, where <options> can be:

Every -t option is mapped into XSLT template. Options after '-t' are mapped into XSLT elements:

There can be multiple --match, --copy-of, --value-of, etc options in a single template, eg. xml sel -t -c "xpath0" -m "xpath1" -m "xpath2" -v "xpath3" -t -m "xpath4" -c "xpath5"

In addition, some global options are available (xml sel <global-options> {<template>} [ <xml-file> ... ]):

To create XML on the fly:

echo "<x/>" | xml sel -t -m / -e xml -e child -a data -o value → <xml><child data="value"/></xml>

To fetch a webpage, and display its title:

wget -qO - https://www.acme.com/feed.xml | xml.exe sel -B -t -m "//title"

To fetch a webpage, and display selected children:

wget -qO - https://www.acme.com/feed.xml | xml.exe sel -B -t -m "//item" -v "title" -n -v "guid" -n -v "enclosure/@url" -n -n

Formating

xml fo [<options>] <xml-file>

<options>:

Editing

xml ed <global-options> {<action>} [ <xml-file-or-uri> ... ]

<global-options>:

<action>:

To remove elements: xml ed -d "/xml/table/rec[@id='2']" xml/table.xml

To move an element: echo '<x id="1"><a/><b/></x>' | xml ed -m "//b" "//a"

To rename elements: xml ed -r "/xml/table/rec" -v record xml/tab-obj.xml

To rename attributes: xml ed -r "//*/@id" -v ID xml/tab-obj.xml

To update an element's value: xml ed -u "/xml/table/rec[@id=1]/numField" -v 0 xml/tab-obj.xml

To update an attribute's value: xml ed -u "/xml/table/rec[@id=3]/@id" -v 5 xml/tab-obj.xml

Resources