<!--
  canonical-url: https://www.avonture.be/fr/blog/linux-xmlstarlet
  published:     2023-12-13
  This is a static plain-Markdown mirror generated at build time.
  Visit the canonical URL above for the fully rendered page, with images and interactive components.
-->

# L'utilitaire xmlstarlet pour Linux

> Maîtrisez la manipulation de données XML en ligne de commande avec xmlstarlet. Ce guide montre comment embellir une sortie XML et filtrer des nœuds avec des expressions XPath

---
![L'utilitaire xmlstarlet pour Linux](/img/v2/bash.webp)

**TL;DR**

Cet article présente `xmlstarlet`, l'équivalent de `jq` pour le XML : formater un XML minifié avec `xmlstarlet format --indent-spaces 4`, et extraire ou filtrer des nœuds avec des expressions XPath via `xmlstarlet sel -t -v`, y compris des filtres sur attribut comme `//book[@category='children']/title`.

`xmlstarlet` est un utilitaire puissant pour Linux qui permet de manipuler des données XML depuis la ligne de commande et qui s'intègre dans vos scripts shell. *Il est au XML ce que [`jq`](/blog/linux-jq) est au JSON.*

Avec `xmlstarlet`, vous pouvez embellir une sortie XML mais aussi la filtrer, par exemple pour n'afficher qu'un nœud donné.

## Un mur de XML en entrée, un mot en sortie {#a-wall-of-xml-in-one-word-out}

Voici le fichier avec lequel nous allons jouer, `data.xml`, exactement tel qu'une machine l'aurait écrit : tout sur une seule ligne, aucun formatage.

**data.xml**

```xml
<?xml version="1.0" encoding="UTF-8"?><bookstore><book category="cooking"><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="web"><title lang="en">XQuery Kick Start</title><author>James McGovern</author><author>Per Bothner</author><author>Kurt Cagle</author><author>James Linn</author><author>Vaidyanathan Nagarajan</author><year>2003</year><price>49.99</price></book><book category="web"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book></bookstore>
```

Posons-lui maintenant une question : *donne-moi le titre du livre classé dans la catégorie `children`*.

```bash
$ cat "data.xml" | xmlstarlet sel -t -v "//book[@category='children']/title"
Harry Potter
```

Une commande, une réponse, et pas une seule ligne de code de parsing.

## Embellir le fichier {#beautifying-the-file}

La deuxième chose que vous utiliserez tous les jours : rendre ce mur lisible, grâce à l'action `format`.

```bash
$ cat "data.xml" | xmlstarlet format --indent-spaces 4
```

```xml
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
    <book category="cooking">
        <title lang="en">Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
    </book>
    <book category="children">
        <title lang="en">Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book category="web">
        <title lang="en">XQuery Kick Start</title>
        <author>James McGovern</author>
        <author>Per Bothner</author>
        <author>Kurt Cagle</author>
        <author>James Linn</author>
        <author>Vaidyanathan Nagarajan</author>
        <year>2003</year>
        <price>49.99</price>
    </book>
    <book category="web">
        <title lang="en">Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
    </book>
</bookstore>
```

## Le voir à l'œuvre avec Docker {#seeing-it-in-action-with-docker}

Avant d'installer quoi que ce soit, essayez les deux commandes ci-dessus dans un container jetable — `data.xml`, exactement le même fichier que celui montré en haut de cet article, vous attend déjà dans le répertoire de travail.

> **Pourquoi Docker d'abord ?:**
>
> Le Dockerfile ci-dessous installe `xmlstarlet` et écrit `data.xml` pour vous. Rien à créer, coller ou télécharger — il n'y a plus qu'à envoyer le fichier dans `xmlstarlet`.

**Dockerfile**

```docker
FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        xmlstarlet && \
    rm -rf /var/lib/apt/lists/*

# The exact data.xml used throughout this article, already in place
RUN mkdir -p /root/demo && \
    printf '%s' '<?xml version="1.0" encoding="UTF-8"?><bookstore><book category="cooking"><title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category="children"><title lang="en">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book><book category="web"><title lang="en">XQuery Kick Start</title><author>James McGovern</author><author>Per Bothner</author><author>Kurt Cagle</author><author>James Linn</author><author>Vaidyanathan Nagarajan</author><year>2003</year><price>49.99</price></book><book category="web"><title lang="en">Learning XML</title><author>Erik T. Ray</author><year>2003</year><price>39.95</price></book></bookstore>' \
        > /root/demo/data.xml

WORKDIR /root/demo

# Signal clearly that this shell runs inside a container
RUN echo "PS1='\n\e[0;33m🐳 \e[0;36m\$(whoami)\e[0m \w # '" >> /root/.bashrc

CMD ["/bin/bash", "-i"]
```

Construisez l'image et lancez-la :

```bash
$ docker build -t xmlstarlet-demo .
[+] Building 9.4s (6/6) FINISHED
✔ exporting to image
$ docker run --rm -it xmlstarlet-demo
🐳 root ~/demo # cat data.xml | xmlstarlet sel -t -v "//book[@category='children']/title"
Harry Potter
```

Même fichier, même filtre, même réponse — pas de `mkdir`, pas de copier-coller de XML dans un nouveau fichier. Essayez ensuite `cat data.xml | xmlstarlet format --indent-spaces 4` pour voir la version embellie, ou modifiez l'expression XPath pour récupérer un autre nœud.

## Installer xmlstarlet {#installing-xmlstarlet}

Pour vérifier si `xmlstarlet` est déjà installé sur votre système, lancez simplement `which xmlstarlet`. Si vous obtenez `xmlstarlet not found` comme réponse :

Prerequisite: xmlstarlet

```bash
$ sudo apt-get update && sudo apt-get -y install xmlstarlet
```

Verify:

```bash
$ xmlstarlet --version

1.6.1
```

## À vous de jouer {#lets-play}

Pour reproduire les deux commandes ci-dessus sur votre machine, ouvrez un shell Linux et lancez `mkdir -p /tmp/xmlstarlet && cd $_`, puis créez un fichier `data.xml` avec le contenu affiché en haut de cet article.

## Comprendre l'expression XPath {#understanding-the-xpath-expression}

Une expression XPath n'est qu'un chemin dans l'arbre. Notre nœud racine s'appelle `bookstore`, ensuite nous avons un ou plusieurs `book` et chaque livre a un `title` :

```xml
<!-- highlight-next-line -->
<bookstore>
    <!-- highlight-next-line -->
    <book category="cooking">
        <!-- highlight-next-line -->
        <title lang="en">Everyday Italian</title>
        [...]
    </book>
    [...]
</bookstore>
```

Parcourez ce chemin depuis la racine et vous obtenez tous les titres du fichier :

```bash
$ cat "data.xml" | xmlstarlet sel -t -v "/bookstore/book/title"

Everyday Italian
Harry Potter
XQuery Kick Start
Learning XML
```

L'expression utilisée au début de cet article, `//book[@category='children']/title`, en est la version filtrée : donne-moi chaque `book`, peu importe où le nœud se trouve (c'est le préfixe `//`), mais uniquement s'il possède un attribut nommé `category` dont la valeur est `children`. Puis, si trouvé, affiche son `title`.

## Conclusion {#conclusion}

Deux actions couvrent l'essentiel des besoins quotidiens : `format` pour rendre un fichier XML lisible par un humain, et `sel -t -v` avec une expression XPath pour en extraire exactement le nœud voulu. Les deux s'utilisent dans un pipe, donc les deux s'utilisent dans un script shell.

Consultez la [documentation officielle](https://xmlstar.sourceforge.net/docs.php) pour en apprendre plus sur xmlstarlet, et si votre prochain fichier est un `.json`, [l'utilitaire jq pour Linux](/blog/linux-jq) raconte exactement la même histoire avec une syntaxe différente.
