PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 13.17 » Annexes » Modules supplémentaires fournis » xml2

F.45. xml2

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

F.45.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.45.2. Description des fonctions

Tableau F.34 montre les fonctions fournies par ce module. Ces fonctions fournissent une analyse XML et les requêtes XPath.

Tableau F.34. Fonctions xml2

Fonction

Description

xml_valid ( document text ) → boolean

Analyse le document donné et renvoie la valeur true si le document est du XML bien formé. (Note : ceci est un alias pour la fonction PostgreSQL native xml_is_well_formed(). Le nom xml_valid() est techniquement incorrect car la validité et le fait d'être bien formé sont deux notions différentes en XML.)

xpath_string ( document text, query text ) → text

Évalue le chemin XPath sur le document fourni, et convertit le résultat en type text.

xpath_number ( document text, query text ) → real

Évalue le chemin XPath sur le document fourni, et convertit le résultat en type real.

xpath_bool ( document text, query text ) → boolean

Évalue le chemin XPath sur le document fourni, et convertit le résultat en type boolean.

xpath_nodeset ( document text, query text, toptag text, itemtag text ) → text

Évalue la requête sur le document et emballe le résultat dans des balises XML. Si le résultat est à plusieurs valeurs, la sortie ressemblera à ceci :

<toptag>
<itemtag>Value 1 which could be an XML fragment</itemtag>
<itemtag>Value 2....</itemtag>
</toptag>
        

Si toptag ou itemtag est une chaîne vide, la balise en question est omise.

xpath_nodeset ( document text, query text, itemtag text ) → text

Identique à xpath_nodeset(document, query, toptag, itemtag) mais le résultat omet toptag.

xpath_nodeset ( document text, query text ) → text

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

xpath_list ( document text, query text, separator text ) → text

Évalue la requête dans le document et renvoie plusieurs valeurs séparées par le séparateur indiqué, par exemple Value 1,Value 2,Value 3 si separator est une virgule (,).

xpath_list ( document text, query text ) → text

Ceci est un emballage pour la fonction ci-dessus qui utilise la virgule (,) comme séparateur.


F.45.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 paramètres sont décrits dans Tableau F.35.

Tableau F.35. Paramètres de xpath_table

ParamètreDescription
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.45.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.45.4. Fonctions XSLT

Les fonctions suivantes sont disponibles si libxslt est installé.

F.45.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.45.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.