Remplacer les fonctions Extract et ExtractValue par XMLQuery

Comme vous l’avez peut-être remarqué, la documentation Oracle 11.2 signale que les fonctions XML Extract(XML) et ExtractValue vont être abandonnées au profit des syntaxes XQUERY inclues dans la base de données Oracle. Vous trouverez ci-dessous des exemples qui montrent comment ré-écrire vos requêtes pour anticiper ces changements de la 12 (ou la version 13!) et surtout dans mon cas pour éviter un bug avec les anciennes syntaxes. Je n’en dis pas plus…

Exemple 1: Extract sans Namespace

Commençons par un exemple d’utilisation assez répandu de la syntaxe extract pour transformer un document XML en ensemble de documents chacun correspondant à un fragment du document d’origine :

select value(p)
from table(
xmlsequence(
extract(
xmltype(
'<oops><x>1</x><y>2</y></oops>'
),
'/oops/*'
)
)
) p;

Avec la fonction XMLQuery, notre select devient

select value(p)
from table(
xmlsequence(
xmlquery(
'/oops/*' passing
xmltype(
'<oops><x>1</x><y>2</y></oops>'
) RETURNING CONTENT
)
)
) p;

Exemple 2: Extract avec un namespace

Si vous utilisez une syntaxe avec des espaces de nommage, la syntaxe est très semblable :

select value(p)
from table(
xmlsequence(
extract(
xmltype(
'<oops xmlns="https://easyteam.fr/demo"><x>1</x><y>2</y></oops>'
),
'/oops/*',
'xmlns="https://easyteam.fr/demo"'
)
)
) p;

Et la transformation avec XMLQuery, n’est guère différente :

select value(p)
from table(
xmlsequence(
xmlquery(
'declare default element namespace "https://easyteam.fr/demo"; /oops/*'
passing xmltype(
'<oops xmlns="https://easyteam.fr/demo"><x>1</x><y>2</y></oops>'
) RETURNING CONTENT
)
)
) p;

Exemple 3: ExtractValue sans Namespace

Dans cet exemple, vous trouverez également une syntaxe très répandue qui permet de retrouver une valeur d’un attribut (unique) d’un document XML à l’aide d’une syntaxe XPATH:

select extractvalue(
xmltype('<oops><x Id="1">1</x><y>2</y></oops>'),
'//@Id')
from dual;

Vous pouvez simplement transformer cet ordre à l’aide de la syntaxe qui suit :

select xmlcast(
xmlquery(
'//@Id' passing
xmltype('<oops><x Id="1">1</x><y>2</y></oops>')
returning content
)
as number)
from dual;

Exemple 4: ExtractValue avec Namespace

Ou pour reprendre l’exemple précédent avec des espaces de nommage :

select extractvalue(
xmltype(
'<oops xmlns="https://easyteam.fr/demo"><x Id="1">1</x><y>2</y></oops>'
),
'//@Id',
'xmlns="https://easyteam.fr/demo"')
from dual;

Cet exemple devient avec XMLQuery et XMLCast :

select xmlcast(
xmlquery(
'declare default element namespace "https://easyteam.fr/demo"; //@Id'
passing
xmltype(
'<oops xmlns="https://easyteam.fr/demo"><x Id="1">1</x><y>2</y></oops>')
returning content
)
as number)
from dual;

Conclusion

Au delà du fait que la transformation est assez simple et qu’elle permet plus simplement de typer vos résultats, vous apprécierez sans doute rapidement l’intérêt de la nouvelle syntaxe quand il s’agira d’exprimer des expressions un peu plus compliquées qu’une simple chaine de recherche XPATH.