PostgreSQLLa base de données la plus sophistiquée au monde.

F.42. xml2

Le module xml2 fournit des fonctionnalités pour les requêtes XPath et pour XSLT.

F.42.1. Notice d'obsolescence

À partir de PostgreSQL™ 8.3, les fonctionnalités XML basées sur le standard SQL/XML sont dans le cœur du serveur. Cela couvre la vérification de la syntaxe XML et les requêtes XPath, ce que fait aussi ce module (en dehors d'autres choses) mais l'API n'est pas du tout compatible. Il est prévu que ce module soit supprimé dans une future version de PostgreSQL pour faire place à une nouvelle API standard, donc vous êtes encouragés à convertir vos applications. Si vous trouvez que des fonctionnalités de ce module ne sont pas disponibles dans un format adéquat avec la nouvelle API, merci d'expliquer votre problème sur la liste pour que ce problème soit corrigé.

F.42.2. Description des fonctions

Tableau F.31, « Fonctions » montre les fonctions fournies par ce module. Ces fonctions fournissent une analyse XML et les requêtes XPath. Tous les arguments sont du type text, ce n'est pas affiché pour que ce soit plus court.

Tableau F.31. Fonctions

Fonction Retour Description
xml_is_well_formed(document) bool

Ceci analyse un document fourni comme argument au format text et renvoie true si le document est du XML bien formé (notez qu'avant PostgreSQL 8.2, cette fonction était appelée xml_valid(). C'est un mauvais nom car un document bien formé n'est pas forcément un document valide en XML. L'ancien nom est toujours disponible mais est obsolète.)

xpath_string(document, query) text

Ces fonctions évaluent la requête XPath à partir du document fourni, et convertie le résultat dans le type spécifié.

xpath_number(document, query) float4
xpath_bool(document, query) bool
xpath_nodeset(document, query, toptag, itemtag) text

Cette fonction évalue la requête sur le document et enveloppe le résultat dans des balises XML. Si le résultat a plusieurs valeurs, la sortie ressemblera à ceci :

<toptag>
<itemtag>Valeur 1 qui pourrait être un fragment XML</itemtag>
<itemtag>Valeur 2....</itemtag>
</toptag>

Si toptag et/ou itemtag sont des chaînes vides, la balise adéquate est omise.

xpath_nodeset(document, query) text

Comme xpath_nodeset(document,query,toptag,itemtag) mais le résultat omet les balises.

xpath_nodeset(document, query, itemtag) text

Comme xpath_nodeset(document,query,toptag,itemtag) mais le résultat omet les balises.

xpath_list(document, query, separator) text

Cette fonction renvoie plusieurs valeurs séparées par le caractère indiqué, par exemple Valeur 1,Valeur 2,Valeur 3 si le séparateur est une virgule (,).

xpath_list(document, query) text Ceci est un emballage de la fonction ci-dessus avec la virgule comme séparateur.

F.42.3. xpath_table

   xpath_table(text key, text document, text relation, text xpaths, text criteria) returns setof record
  

xpath_table est une fonction SRF qui évalue un ensemble de requêtes XPath sur chaque ensemble de documents et renvoie les résultats comme une table. Le champ de clé primaire de la table des documents est renvoyé comme première colonne des résultats pour que les résultats puissent être utilisés dans des jointures. Les pamraètres sont décrits dans Tableau F.32, « Paramètres de xpath_table ».

Tableau F.32. Paramètres de xpath_table

Paramètre Description
key

Le nom du champ de la clé primaire (« key »). C'est simplement le champ à utiliser comme première colonne de la table en sortie, autrement dit celle qui identifie l'enregistrement (voir la note ci-dessous sur les valeurs multiples).

document

Le nom du champ contenant le document XML.

relation

Le nom de la table ou de la vue contenant les documents.

xpaths

Une ou plusieurs expressions XPath séparées par des |

criteria

Le contenu de la clause WHERE. Elle doit être spécifiée, donc utilisez true ou 1=1 si vous voulez traiter toutes les lignes de la relation.


Ces paramètres (en dehors des chaînes XPath) sont simplement substitués dans une instruction SELECT, donc vous avez de la flexibilité. L'instruction est celle qui suit :

SELECT <key>, <document> FROM <relation> WHERE <criteria>

Donc les paramètres peuvent être tout ce qui est valide dans ces emplacements particuliers. Le résultat de ce SELECT a besoin de renvoyer exactement deux colonnes (ce qu'il fera sauf si vous essayez d'indiquer plusieurs champs pour la clé ou le document). Cette approche simpliste implique que vous validiez avant tout valeur fournie par un utilisateur pour éviter les attaques par injection de code SQL.

La fonction doit être utilisée dans une expression FROM avec une clause AS pour indiquer les colonnes en sortie. Par exemple :

SELECT * FROM
xpath_table('article_id',
            'article_xml',
            'articles',
            '/article/author|/article/pages|/article/title',
            'date_entered > ''2003-01-01'' ')
AS t(article_id integer, author text, page_count integer, title text);
  

La clause AS définit les noms et types des colonnes de la table en sortie. La première est le champ « key » et le reste correspond à la requête XPath. S'il y a plus de requêtes XPath que de colonnes résultats, les requêtes supplémentaires seront ignorées, S'il y a plus de colonnes résultats que de requêtes XPath, les colonnes supplémentaires seront NULL.

Notez que cet exemple définit la colonne résultat page_count en tant qu'entier (integer). La fonction gère en interne les représentations textes, donc quand vous dites que vous voulez un entier en sortie, il prendra la représentation texte du résultat XPath et utilisera les fonctions en entrée de PostgreSQL pour la transformer en entier (ou tout type que la clause AS réclame). Vous obtiendrez une erreur s'il ne peut pas le faire -- par exemple si le résultat est vide -- donc rester sur du texte est préférable si vous pensez que vos données peuvent poser problème.

L'instruction SELECT n'a pas besoin d'être un SELECT *. Elle peut référencer les colonnes par nom ou les joindre à d'autres tables. La fonction produit une table virtuelle avec laquelle vous pouvez réaliser toutes les opérations que vous souhaitez (c'est-à-dire agrégation, jointure, tri, etc.) Donc nous pouvons aussi avoir :

SELECT t.title, p.fullname, p.email
FROM xpath_table('article_id', 'article_xml', 'articles',
                 '/article/title|/article/author/@id',
                 'xpath_string(article_xml,''/article/@date'') > ''2003-03-20'' ')
       AS t(article_id integer, title text, author_id integer),
     tblPeopleInfo AS p
WHERE t.author_id = p.person_id;
  

comme exemple plus compliqué. Bien sûr, vous pouvez placer tout ceci dans une vue pour une utilisation plus simple.

F.42.3.1. Résultats à plusieurs valeurs

La fonction xpath_table suppose que les résultats de chaque requête XPath ramènent plusieurs valeurs, donc le nombre de lignes renvoyées par la fonction pourrait ne pas être le même que le nombre de documents en entrée. La première ligne renvoyée contient le premier résultat de chaque requête, la deuxième le second résultat de chaque requête. Si une res requêtes a moins de valeur que les autres, des valeurs NULL seront renvoyées.

Dans certains cas, un utilisateur saura qu'une requête XPath renverra seulement un seul résultat, peut-être un identifiant unique de document) -- si elle est utilisée avec une requête XPath renvoyant plusieurs résultats, le résultat sur une ligne apparaîtra seulement sur la première ligne du résultat. La solution à cela est d'utiliser le champ clé pour une jointure avec une requête XPath. Comme exemple :

    CREATE TABLE test (
        id int PRIMARY KEY,
        xml text
    );

    INSERT INTO test VALUES (1, '<doc num="C1">
    <line num="L1"><a>1</a><b>2</b><c>3</c></line>
    <line num="L2"><a>11</a><b>22</b><c>33</c></line>
    </doc>');

    INSERT INTO test VALUES (2, '<doc num="C2">
    <line num="L1"><a>111</a><b>222</b><c>333</c></line>
    <line num="L2"><a>111</a><b>222</b><c>333</c></line>
    </doc>');

    SELECT * FROM
      xpath_table('id','xml','test',
                  '/doc/@num|/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
                  'true')
      AS t(id int, doc_num varchar(10), line_num varchar(10), val1 int4, val2 int4, val3 int4)
    WHERE id = 1 ORDER BY doc_num, line_num

     id | doc_num | line_num | val1 | val2 | val3
    ----+---------+----------+------+------+------
      1 | C1      | L1       |    1 |    2 |    3
      1 |         | L2       |   11 |   22 |   33
   

Pour obtenir doc_num sur chaque ligne, la solution est d'utiliser deux appels à xpath_table et joindre les résultats :

   SELECT t.*,i.doc_num FROM
     xpath_table('id', 'xml', 'test',
                 '/doc/line/@num|/doc/line/a|/doc/line/b|/doc/line/c',
                 'true')
       AS t(id int, line_num varchar(10), val1 int4, val2 int4, val3 int4),
     xpath_table('id', 'xml', 'test', '/doc/@num', 'true')
       AS i(id int, doc_num varchar(10))
   WHERE i.id=t.id AND i.id=1
   ORDER BY doc_num, line_num;

    id | line_num | val1 | val2 | val3 | doc_num
   ----+----------+------+------+------+---------
     1 | L1       |    1 |    2 |    3 | C1
     1 | L2       |   11 |   22 |   33 | C1
   (2 rows)
   

F.42.4. Fonctions XSLT

Les fonctions suivantes sont disponibles si libxslt est installé.

F.42.4.1. xslt_process

    xslt_process(text document, text stylesheet, text paramlist) returns text
   

Cette fonction applique la feuille de style XSLT au document et renvoie le résultat transformé. Le paramètre paramlist est une liste de paramètres à utiliser dans la transformation, spécifiée sous la forme 'a=1,b=2'. Notez que l'analyse des paramètres est simpliste : les valeurs des paramètres ne peuvent pas contenir de virgules !

Il existe aussi une version de xslt_process à deux paramètres qui ne passe pas de paramètres pour la transformation.

F.42.5. Auteur

John Gray

Le développement de ce module a été sponsorisé par Torchbox Ltd. (www.torchbox.com) Il utilise la même licence BSD que PostgreSQL.