Le module xml2
fournit des fonctionnalités pour les
requêtes XPath et pour XSLT.
À 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 <pgsql-hackers@lists.postgresql.org>
pour que ce problème soit corrigé.
Tableau F.35 montre les fonctions fournies par ce module. Ces fonctions fournissent une analyse XML et les requêtes XPath.
Tableau F.35. Fonctions xml2
Fonction Description |
---|
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 |
Évalue le chemin XPath sur le document fourni, et convertit le résultat
en type |
Évalue le chemin XPath sur le document fourni, et convertit le résultat
en type |
Évalue le chemin XPath sur le document fourni, et convertit le résultat
en type |
É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 |
Identique à |
Identique à |
Évalue la requête dans le document et renvoie plusieurs valeurs
séparées par le séparateur indiqué, par exemple |
Ceci est un emballage pour la fonction ci-dessus qui utilise la
virgule ( |
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.36.
Tableau F.36. 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 |
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.
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)
Les fonctions suivantes sont disponibles si libxslt est installé.
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.
John Gray <jgray@azuli.co.uk>
Le développement de ce module a été sponsorisé par Torchbox Ltd. (www.torchbox.com) Il utilise la même licence BSD que PostgreSQL.