Pourquoi un format XML pour les recettes de cuisine?

Le but du format est de permettre l'échange informatique de recettes de cuisine et éviter ainsi d'avoir à ressaisir encore et encore le texte des recettes que l'on s'échange, que l'on publie sur un blog ou que l'on enregistre dans un logiciel de gestion de recettes de cuisine.

Il est important de souligner à ce stade que le format recipe-XML comme tout autre format XML n'a pas pour destination principale d'être lu par les humains (même s'il est lisible par un humain) mais d'être produit et lu automatiquement par des ordinateurs. On lui pardonnera donc d'être verbeux.

Il se doit par contre d'être précis, de façon à ce que l'échange de recettes se fasse sans erreur. Et c'est donc tout l'objet de ce guide que de l'expliquer de la façon la plus précise possible.

Explication pas à pas du format recipe-XML

Plus petite recette permise, notions XML de base

Une recette doit avoir au mininum :

La plus petite recette s'écrit donc comme ceci dans le format recipe-XML:

<recipe>
  <title>Crêpes</title>
  <ingredient_lines>
    <yield unit="pers.">6</yield>
    <ingredient_line>
      <quantity unit="kg">1</quantity>
      <ingredient>farine</ingredient>
    </ingredient_line>
  </ingredient_lines>
</recipe>

XML est un langage permettant de mettre en forme des documents grâce à des balises. Une balise est une chaîne de caractères placée entre un caractère < et un caractère >, par exemple <title>.

Une balise ouvrante indique le début d'un élément. L'élément se termine ensuite par une balise fermante. Dans l'exemple ci-dessus, la balise ouvrante <title> indique le début de l'élément "titre" de la recette et la balise fermante </title> en indique sa fin.

Notons au passage que les balises sont en anglais pour assurer la meilleure standardisation possible du format. Et comme indiqué au début, le but d'un document XML n'est pas d'être lu par un humain.

Le corps d'un document XML est une arborescence d'éléments imbriqués, avec un élément racine unique. L'élément racine est ici l'élément <recipe> … </recipe>.

Cet élément contient un élément "titre": <title> … </title> et un élément "lignes d'ingrédient" <ingredient_lines> … </ingredient_lines>.

Auteur de la recette, système de mesures

Un élément peut avoir des attributs. C'est le cas de l'élément recipe qui peut avoir comme attributs:

Note
Ces trois attributs sont obligatoires si la racine du document est l'élément recipe et optionnels si l'élément recipe est imbriqué dans d'autres éléments de plus haut niveau.

La plus petite recette complétée avec ces attributs devient:

<recipe schema_version="0.2" owned_by="philippe" measures="FR">
  <title>Crêpes</title>
  <ingredient_lines>
    <yield unit="pers.">6</yield>
    <ingredient_line>
      <quantity unit="kg">1</quantity>
      <ingredient>farine</ingredient>
    </ingredient_line>
  </ingredient_lines>
</recipe>

Historique des changements (élément change_history)

L'historique des changements de la recette permet de retracer son origine et les changements qui y ont été apportés. Il inclut les trois éléments suivants:

Les dates doivent être des dates valides au sens de XML Schema.

Note
Ces trois éléments sont optionnels.

Exemple:

  <change_history>
    <last_updated on="2007-07-01T14:58:41Z"/>
    <recorded on="2006-03-21T00:00:00Z"/>
    <source>Marie-Claude Bégou</source>
  </change_history>

Quantité produite par la recette (élément yield), quantité d'un ingrédient (élément quantity)

Une quantité est valide si elle remplit les conditions suivantes:

Ces différents nombres doivent satisfaire les expressions régulières suivantes:

Un entier valide [0-9]+
Un nombre décimal valide [0-9]+\.[0-9]+
Une fraction valide [0-9]+\/[0-9]+
Un entier suivi d'une fraction valide [0-9]+ [0-9]+\/[0-9]+

Quelques exemples de quantités valides sont donnés ci-dessous:

Une quantité doit avoir une dimension (unité de mesure) ou un qualifiant de dimension (petit, moyen, etc.). Cette dimension est exprimée par l' attribut unit, piece ou qualifier de l'élément.

Exemple:

      <quantity unit="kg">1</quantity>

Lignes d'ingrédient (élements ingredient_lines et ingredient_line)

La liste d'ingrédients d'une recette est organisée comme une liste ordonnée de lignes d'ingrédient.

Une ligne d'ingrédient peut être de trois types: une ligne d'ingrédient simple (type="simple"), un groupe d'ingrédient (type="group") ou une référence de recette (type="ref").

Une ligne d'ingrédient dont le type est omis est considérée comme une ligne d'ingrédient simple. Une ligne d'ingrédient simple comporte deux éléments: l'élément quantity et l'élément ingredient.

      <ingredient_line>
        <quantity unit="g">250</quantity>
        <ingredient>sucre</ingredient>
      </ingredient_line>

Un groupe d'ingrédient a un nom (élément name obligatoire) et regroupe les lignes d'ingrédient simples qui lui sont imbriquées.

    <ingredient_line type="group">
      <name>sirop</name>
      <ingredient_line>
        <quantity unit="g">250</quantity>
        <ingredient>sucre</ingredient>
      </ingredient_line>
      <ingredient_line>
        <quantity piece="verre">1</quantity>
        <ingredient>eau</ingredient>
      </ingredient_line>
      <ingredient_line>
        <quantity piece=" ">1/2</quantity>
        <ingredient>citron</ingredient>
      </ingredient_line>
    </ingredient_line>

Une référence de recette est un moyen d'inclure une quantité produite par une autre recette de base comme sous-recette de la recette en cours. Par exemple la recette de pizza dont un extrait figure ci-dessous fait usage de 700 g de pâte produite par la recette de pâte à pizza.

   <ingredient_line type="ref">
      <quantity unit="g">700</quantity>
      <recipe>pâte à pizza</recipe>
    </ingredient_line>

Instructions (éléments steps, instructions)

Les instructions d'une recette peuvent être indiquées de deux manières, soit en texte libre en utilisant l'élément instructions:

  <instructions>Mélanger oeufs battus en omelette et sucre. Ajoutez farine, blé noir, huile  et lait.
  </instructions>

Ou bien elles peuvent être indiquées étape par étape, en utilisant les éléments steps et step, comme dans l'exemple qui suit:

  <steps>
    <step type="undefined" duration="PT5M">
      <instructions>Préchauffez le four à th. 5-6.</instructions>
    </step>
    <step type="preparation" duration="PT5M">
      <link mode="starts in parallel to" step="1"/>
      <instructions>Fendez la gousse de vanille dans le sens de la longueur. Avec une petite cuillère, raclez les graines et faites-les tomber dans un saladier. Ajoutez la canelle, les jaunes d'oeuf, le sucre, la crême fraîche et le lait. Fouettez bien le tout.</instructions>
    </step>
    <step type="cooking" duration="PT30M">
      <link mode="starts after" step="1"/>
      <instructions>Versez l'appareil dans les ramequins en porcelaine à feu et faites cuire pendant 30 minutes.</instructions>
    </step>
    <step type="cooling" duration="PT1H">
      <link mode="starts after" step="3"/>
      <instructions>Laissez refroidir et mettez au réfrigérateur.</instructions>
    </step>
    <step type="cooking" duration="PT8M">
      <link mode="starts after" step="4"/>
      <instructions>Saupoudrez de cassonade et passez 7 à 8 minutes sous le gril très chaud. Servez caramélisé.</instructions>
    </step>
  </steps>

Chaque étape est représentée par un élément step. L'ordre dans lequel les les éléments steps sont listés est bien sûr significatif. Il correspond à l'ordre de lecture habituel des étapes d'une recette. Chaque étape est donc identifiée implicitement par un numéro de séquence (commençant à 1) qui est l'ordre d'apparition de l'étape dans la liste des étapes steps.

L'élément step possède deux attributs type et duration.

L'attribut type permet d'indiquer le type de l'étape, par exemple preparation, cuisson, etc. Cette valeur est pour l'instant du texte libre.

L'attribut duration indique la durée de réalisation de l'étape. Cette durée doit être une durée valide au sens du type duration de XML Schema, avec des restrictions imposées par le format recipe-XML:

L'élément link permet de lier les étapes entre elles et par là d'indiquer dans quel ordre les étapes doivent être exécutées (graphe d'exécution). Il possède à cet effet deux attributs: mode et step.

L'attribut step permet d'indiquer le numéro de séquence de l'étape à laquelle l'étape courante est liée. L'attribut mode permet d'indiquer comment ces deux étapes sont liées; il peut prendre une des valeurs suivantes:

Notes (élément notes)

L'élément notes permet d'ajouter des notes ou conseils en texte libre pour aider à la réalisation de la recette.

Le classement de la recette (éléments catalogued_in et catalog)

Une recette peut être classée dans zéro à plusieurs catalogues. Le nom du catalogue est indiqué par l'attribut name de l'élément catalog. La référence dans le catalogue est le contenu de l'élément catalog. Le soin de normaliser ou non cette référence est laissé à la liberté de chaque application de gestion de recettes de cuisine.

  <catalogued_in>
    <catalog name="plat">dessert</catalog>
    <catalog name="difficulté">moyenne</catalog>
    <catalog name="toques">2</catalog>
  </catalogued_in>

Système de mesure

Il est anticipé d'avoir un système de mesure par pays. Le système français, noté FR, comprend les mesures suivantes:

Mesures standardisées (type="unit"):

Mesures approximatives (type="piece"):

Qualifiants (type="qualifier"):

Un exemple de document complet pour une recette de crêpes

<?xml version="1.0" encoding="UTF-8"?>
<recipe schema_version="0.2" measures="FR" owned_by="Philippe Bégou">
  <title>Crêpes</title>
  <catalogued_in>
    <catalog name="plat">autre</catalog>
    <catalog name="difficulté">moyenne</catalog>
    <catalog name="toques">2</catalog>
  </catalogued_in>
  <ingredient_lines>
    <yield piece="pers.">6</yield>
    <ingredient_line>
      <quantity unit="g">150</quantity>
      <ingredient>sucre</ingredient>
    </ingredient_line>
    <ingredient_line>
      <quantity unit="g">750</quantity>
      <ingredient>farine</ingredient>
    </ingredient_line>
    <ingredient_line>
      <quantity piece=" ">8</quantity>
      <ingredient>oeuf</ingredient>
    </ingredient_line>
    <ingredient_line>
      <quantity piece="c. à café">4</quantity>
      <ingredient>blé noir</ingredient>
    </ingredient_line>
    <ingredient_line>
      <quantity piece="c. à soupe">4</quantity>
      <ingredient>huile</ingredient>
    </ingredient_line>
    <ingredient_line>
      <quantity unit="l">2</quantity>
      <ingredient>lait</ingredient>
    </ingredient_line>
    <ingredient_line>
      <quantity piece="c. à soupe">1</quantity>
      <ingredient>gros sel</ingredient>
    </ingredient_line>
  </ingredient_lines>
  <instructions>Mélanger oeufs battus en omelette et sucre. Ajoutez farine, blé noir, huile  et lait.
  </instructions>
  <change_history>
    <last_updated on="2007-07-01T14:58:41Z"/>
    <recorded on="2006-03-21T00:00:00Z"/>
    <source>Marie-Claude Bégou</source>
  </change_history>
</recipe>

Note aux développeurs

La spécification du format recipe-XML est disponible sous forme d'un schéma XML à l'adresse suivante: http://www.amisgourmands.fr/schemas/0.2/recipe.xsd

En complément du schéma XML, il faut également vérifier les règles suivantes qui sont également applicables: