
{"id":713,"date":"2009-08-10T09:16:16","date_gmt":"2009-08-10T08:16:16","guid":{"rendered":"http:\/\/dasini.net\/blog\/?p=713"},"modified":"2009-09-16T09:58:03","modified_gmt":"2009-09-16T08:58:03","slug":"utiliser-xml-avec-mysql-5-1-part-35","status":"publish","type":"post","link":"https:\/\/dasini.net\/blog\/2009\/08\/10\/utiliser-xml-avec-mysql-5-1-part-35\/","title":{"rendered":"Utiliser XML avec MySQL 5.1 (part 3\/5)"},"content":{"rendered":"<p><!-- \t\t@page { margin: 2cm } \t\tP { margin-bottom: 0.21cm } \t\tH2 { margin-bottom: 0.21cm } \t\tH2.western { font-family: \"Arial\", sans-serif; font-size: 14pt; font-style: italic } \t\tH2.cjk { font-family: \"MS Mincho\"; font-size: 14pt; font-style: italic } \t\tH2.ctl { font-family: \"Tahoma\"; font-size: 14pt; font-style: italic } --><\/p>\n<p style=\"margin-bottom: 0cm;\">(<a title=\"Utiliser XML avec MySQL 5.1 (part 2\/5)\" href=\"http:\/\/dasini.net\/blog\/2009\/07\/29\/utiliser-xml-avec-mysql-5-1-part-25\/\">&lt;- pr\u00e9c\u00e9dent<\/a>)<\/p>\n<p><!-- \t\t@page { margin: 2cm } \t\tP { margin-bottom: 0.21cm } \t\tH2 { margin-bottom: 0.21cm } \t\tH2.western { font-family: \"Arial\", sans-serif; font-size: 14pt; font-style: italic } \t\tH2.cjk { font-family: \"MS Mincho\"; font-size: 14pt; font-style: italic } \t\tH2.ctl { font-family: \"Tahoma\"; font-size: 14pt; font-style: italic } \t\tH4 { margin-bottom: 0.21cm } \t\tH4.western { font-family: \"Arial\", sans-serif; font-size: 11pt; font-style: italic } \t\tH4.cjk { font-family: \"MS Mincho\"; font-size: 11pt; font-style: italic } \t\tH4.ctl { font-family: \"Tahoma\"; font-size: 11pt; font-style: italic } \t\tTD P { margin-bottom: 0.21cm } --><\/p>\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<h2>Interroger un flux XML avec Xpath<\/h2>\n<p style=\"margin-bottom: 0cm;\">L&#8217;emploi de XML ne pr\u00e9senterait pas beaucoup d&rsquo;int\u00e9r\u00eat sans la possibilit\u00e9 de pouvoir interroger sa structure pour acc\u00e9der \u00e0 une information particuli\u00e8re : le langage <em>XPath<\/em> r\u00e9pond \u00e0 cette attente et est (en partie du moins) aujourd&rsquo;hui int\u00e9gr\u00e9 \u00e0 MySQL. Mais avant de voir comment utiliser <em>XPath<\/em> \u00e0 travers MySQL, il est n\u00e9cessaire de se pencher sur la syntaxe de ses expressions, dont la construction la plus importante est sans conteste le chemin de <em>localisation<\/em> (<em>location path<\/em>).<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">\n<h4>Le chemin de localisation<\/h4>\n<p style=\"margin-bottom: 0cm;\">De mani\u00e8re similaire \u00e0 la navigation au sein d&rsquo;un syst\u00e8me de fichiers, un chemin de localisation se compose d&rsquo;une succession d&rsquo;\u00e9tapes, s\u00e9par\u00e9es les unes des autres par un <span style=\"text-decoration: underline;\">\/<\/span>. La description d&rsquo;un chemin peut se faire de fa\u00e7on absolue ou relative, auquel cas un n\u0153ud contexte est utilis\u00e9 afin de d\u00e9terminer \u00e0 partir de quel endroit doit s&rsquo;effectuer la recherche.<\/p>\n<p style=\"margin-bottom: 0cm;\">Chaque \u00e9tape d&rsquo;un chemin de localisation peut se diviser en trois parties (axe de recherche, test du n\u0153ud et ensemble de pr\u00e9dicats), r\u00e9unies sous la forme suivante :<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm; text-decoration: none;\"><strong>Axis::Node-Test[Predicate1][Predicate2]&#8230;<\/strong><\/p>\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<h4>L&rsquo;axe de recherche (Axis)<\/h4>\n<p style=\"margin-bottom: 0cm;\">L&rsquo;axe de recherche permet de sp\u00e9cifier dans quel <em>sens<\/em> orienter la s\u00e9lection des n\u0153uds que l&rsquo;on veut r\u00e9cup\u00e9rer par rapport au n\u0153ud courant. Ainsi, il est possible de choisir de chercher dans l&rsquo;ensemble des n\u0153uds des descendants, plut\u00f4t que de se limiter (par d\u00e9faut) aux n\u0153uds directement enfants.<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">Il existe une dizaine d&rsquo;axes de recherche, dont les plus usit\u00e9s sont :<\/p>\n<ul>\n<li><span style=\"font-style: normal;\"><strong>child<\/strong><\/span>, \tqui limite \u00e0 l&rsquo;exploration des n\u0153uds \u00e9l\u00e9ments directement \tenfants du n\u0153ud contexte,<\/li>\n<li><span style=\"font-style: normal;\"><strong>descendant<\/strong><\/span>, \tqui englobe, en plus des n\u0153uds enfants, tous les \u00e9l\u00e9ments \tdescendants,<\/li>\n<li><span style=\"font-style: normal;\"><strong>descendant-or-self<\/strong><\/span>, \tidentique \u00e0 descendant avec en plus le n\u0153ud contexte inclus,<\/li>\n<li><span style=\"font-style: normal;\"><strong>ancestor<\/strong><\/span>, \tqui contient tous les n\u0153uds anc\u00eatres,<\/li>\n<li><span style=\"font-style: normal;\"><strong>ancestor-or-self<\/strong><\/span>, \tidentique \u00e0 ancestor avec en plus le n\u0153ud contexte,<\/li>\n<li><span style=\"font-style: normal;\"><strong>following-sibling<\/strong><\/span>, \tqui fait r\u00e9f\u00e9rence aux \u00e9l\u00e9ments fr\u00e8res suivants,<\/li>\n<li><span style=\"font-style: normal;\"><strong>preceding-sibling<\/strong><\/span>, \tqui fait r\u00e9f\u00e9rence aux \u00e9l\u00e9ments fr\u00e8res pr\u00e9c\u00e9dents,<\/li>\n<li><span style=\"font-style: normal;\"><strong>attribute<\/strong><\/span>, \tqui se cantonne \u00e0 la recherche dans les n\u0153uds attributs.<\/li>\n<\/ul>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">\n<h4>Le test du n\u0153ud (Node-Test)<\/h4>\n<p style=\"margin-bottom: 0cm;\">G\u00e9n\u00e9ralement, le test repose sur le nom du n\u0153ud que l&rsquo;on veut retrouver. Cependant, <em>XPath<\/em> ne se limite pas \u00e0 la recherche de simples \u00e9l\u00e9ments, mais \u00e0 tous types de n\u0153uds. Il est donc ainsi possible de pr\u00e9ciser le type de n\u0153ud que l&rsquo;on veut atteindre gr\u00e2ce aux fonctions suivantes :<\/p>\n<ul>\n<li><span style=\"text-decoration: none;\"><strong>node()<\/strong><\/span>, \tqui valide tous types de n\u0153uds,<\/li>\n<li><span style=\"text-decoration: none;\"><strong>text()<\/strong><\/span>, \tpour les n\u0153uds texte,<\/li>\n<li><span style=\"text-decoration: none;\"><strong>comment()<\/strong><\/span>, \tpour les commentaires,<\/li>\n<li><span style=\"text-decoration: none;\"><strong>processing-instruction()<\/strong><\/span>, \tpour les instructions de traitements.<\/li>\n<\/ul>\n<h4>Les pr\u00e9dicats (Predicates)<\/h4>\n<p style=\"margin-bottom: 0cm;\">Les pr\u00e9dicats, d\u00e9limit\u00e9s par un <span style=\"font-weight: normal;\">\u00ab\u00a0<\/span><span style=\"text-decoration: none;\"><strong>[<\/strong><\/span><span style=\"text-decoration: none;\"><span style=\"font-weight: normal;\">\u00ab\u00a0<\/span><\/span> et un <span style=\"font-weight: normal;\">\u00ab\u00a0<\/span><span style=\"text-decoration: none;\"><strong>]<\/strong><\/span><span style=\"text-decoration: none;\"><span style=\"font-weight: normal;\">\u00ab\u00a0<\/span><\/span>, permettent de filtrer plus finement l&rsquo;ensemble des n\u0153uds retrouv\u00e9s par le chemin de localisation, en \u00e9valuant l&rsquo;expression qu&rsquo;ils contiennent et en ne retenant que les n\u0153uds qui la valident. Plusieurs pr\u00e9dicats peuvent se suivre, filtrant ainsi un peu plus pr\u00e9cis\u00e9ment l&rsquo;ensemble des n\u0153uds \u00e0 garder.<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">Les expressions mises en place dans les pr\u00e9dicats peuvent, en plus des quelques fonctions existantes et des op\u00e9rateurs habituels, exploiter des ensembles de n\u0153uds (<em>node-sets<\/em>) r\u00e9cup\u00e9r\u00e9s gr\u00e2ce \u00e0&#8230; des chemins de localisation !<\/p>\n<p style=\"margin-bottom: 0cm;\">Ainsi, il est possible d&rsquo;adapter la validit\u00e9 d&rsquo;un chemin de localisation en fonction m\u00eame de tout \u00e9l\u00e9ment de l&rsquo;arborescence du flux <em>XML<\/em>.<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">Par exemple, si l&rsquo;on consid\u00e8re l&rsquo;expression <em>XPath<\/em> suivante :<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm; text-decoration: none;\"><strong>\/\/article[@rubrique = \/site\/menu\/rubrique[2]]<\/strong><\/p>\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<p style=\"margin-bottom: 0cm;\">On r\u00e9cup\u00e8re tous les articles qui poss\u00e8dent un attribut rubrique ayant la m\u00eame valeur que la deuxi\u00e8me rubrique du menu du site.<\/p>\n<p style=\"margin-bottom: 0cm;\">Cet autre exemple :<\/p>\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<p style=\"margin-bottom: 0cm; text-decoration: none;\"><strong>\/\/article[not( @rubrique = preceding-sibling::article\/@rubrique)]<\/strong><\/p>\n<p style=\"margin-bottom: 0cm; text-decoration: none;\">\n<p style=\"margin-bottom: 0cm;\">permet de ne s\u00e9lectionner que les articles qui n&rsquo;ont pas leur attribut rubrique \u00e9gal \u00e0 l&rsquo;attribut rubrique d&rsquo;un article pr\u00e9c\u00e9dent. En d&rsquo;autres termes, on ne r\u00e9cup\u00e8re ici que le premier article de chaque rubrique.<\/p>\n<h4>Quelques raccourcis<\/h4>\n<p style=\"margin-bottom: 0cm;\">Afin de faciliter la lecture et l&rsquo;\u00e9criture de requ\u00eates <em>XPath<\/em>, il existe bien heureusement un ensemble de raccourcis pratiques:<\/p>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\"><span style=\"text-decoration: underline;\"><span style=\"background: transparent none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;\">Raccourcis Xpath<\/span><\/span><\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"4\" width=\"303\" bordercolor=\"#000000\">\n<col width=\"185\"><\/col>\n<col width=\"99\"><\/col>\n<thead>\n<tr valign=\"top\">\n<td width=\"185\">self::node()<\/td>\n<td width=\"99\">.<\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr valign=\"top\">\n<td width=\"185\">parent::node()<\/td>\n<td width=\"99\">..<\/td>\n<\/tr>\n<tr valign=\"top\">\n<td width=\"185\">attribute::name<\/td>\n<td width=\"99\">@name<\/td>\n<\/tr>\n<tr valign=\"top\">\n<td width=\"185\">\/\/descendant-or-self::node()\/<\/td>\n<td width=\"99\">\/\/<\/td>\n<\/tr>\n<tr valign=\"top\">\n<td width=\"185\">element[position() = X]<\/td>\n<td width=\"99\">element[X]<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\">\n<p style=\"margin-bottom: 0cm;\"><em>(<a title=\"Utiliser XML avec MySQL 5.1 (part 4\/5)\" href=\"http:\/\/dasini.net\/blog\/2009\/09\/16\/utiliser-xml-avec-mysql-5-1-part-45\/\">\u00e0 suivre&#8230; utiliser XML avec MySQL 5.1 : Les fonctionnalit\u00e9s Xpath de MySQL 5<\/a>)<\/em><\/p>\n<p style=\"margin-bottom: 0cm;\">\n","protected":false},"excerpt":{"rendered":"<p>Interroger un flux XML avec Xpath<\/p>\n<p>L&#8217;emploi de XML ne pr\u00e9senterait pas beaucoup d&rsquo;int\u00e9r\u00eat sans la possibilit\u00e9 de pouvoir interroger sa structure pour acc\u00e9der \u00e0 une information particuli\u00e8re : le langage XPath r\u00e9pond \u00e0 cette attente et est (en partie du moins) aujourd&rsquo;hui int\u00e9gr\u00e9 \u00e0 MySQL. Mais avant de voir comment utiliser XPath \u00e0 travers MySQL, il est n\u00e9cessaire de se pencher sur la syntaxe de ses expressions, dont la construction la plus importante est sans conteste le chemin de localisation (location path).<\/p>\n<p>Le chemin de localisation<\/p>\n<p>De mani\u00e8re similaire \u00e0 la navigation au sein d&rsquo;un syst\u00e8me de fichiers, un chemin de localisation se compose d&rsquo;une succession d&rsquo;\u00e9tapes, s\u00e9par\u00e9es les unes des autres par un \/. La description d&rsquo;un chemin peut se faire de fa\u00e7on absolue ou relative, auquel cas un n\u0153ud contexte est utilis\u00e9 afin de d\u00e9terminer \u00e0 partir de quel endroit doit s&rsquo;effectuer la recherche.<\/p>\n<p>Chaque \u00e9tape d&rsquo;un chemin de localisation peut se diviser en trois parties (axe de recherche, test du n\u0153ud et ensemble de pr\u00e9dicats), r\u00e9unies sous la forme suivante :<\/p>\n<p>Axis::Node-Test[Predicate1][Predicate2]&#8230;<\/p>\n<p>L&rsquo;axe de recherche (Axis)<\/p>\n<p>L&rsquo;axe de recherche permet de sp\u00e9cifier dans quel sens orienter la s\u00e9lection des n\u0153uds que l&rsquo;on veut r\u00e9cup\u00e9rer par rapport au n\u0153ud courant. Ainsi, il est possible de choisir de chercher dans l&rsquo;ensemble des n\u0153uds des descendants, plut\u00f4t que de se limiter (par d\u00e9faut) aux n\u0153uds directement enfants.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":""},"categories":[8],"tags":[77,78],"class_list":["post-713","post","type-post","status-publish","format-standard","hentry","category-mysql","tag-xml","tag-xpath"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9LfWW-bv","jetpack-related-posts":[{"id":758,"url":"https:\/\/dasini.net\/blog\/2009\/09\/16\/utiliser-xml-avec-mysql-5-1-part-45\/","url_meta":{"origin":713,"position":0},"title":"Utiliser XML avec MySQL 5.1 (part 4\/5)","author":"Olivier DASINI","date":"16 septembre 2009","format":false,"excerpt":"Les fonctionnalit\u00e9s XPath de MySQL 5 MySQL 5 offre la possibilit\u00e9 de pouvoir ex\u00e9cuter des requ\u00eates XPath sur un flux XML, gr\u00e2ce \u00e0 la fonction extractValue(). Le r\u00e9sultat r\u00e9cup\u00e9r\u00e9 est la concat\u00e9nation de la valeur textuelle de chacun des n\u0153uds trouv\u00e9s (chaque valeur \u00e9tant dissoci\u00e9e des autres par un espace\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":691,"url":"https:\/\/dasini.net\/blog\/2009\/07\/29\/utiliser-xml-avec-mysql-5-1-part-25\/","url_meta":{"origin":713,"position":1},"title":"Utiliser XML avec MySQL 5.1 (part 2\/5)","author":"Olivier DASINI","date":"29 juillet 2009","format":false,"excerpt":"Ins\u00e9rer du XML dans MySQL Un fichier XML, n'est finalement qu'un fichier contenant du texte et ins\u00e9rer du texte dans un SGBDR, est loin d'\u00eatre la chose la plus difficile. Une simple requ\u00eate INSERT fait l'affaire. Cela nous donne quelque chose comme ceci : INSERT INTO ma_table (champ_texte) VALUES ('...')","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":779,"url":"https:\/\/dasini.net\/blog\/2009\/10\/01\/utiliser-xml-avec-mysql-5-1-part-55\/","url_meta":{"origin":713,"position":2},"title":"Utiliser XML avec MySQL 5.1 (part 5\/5)","author":"Olivier DASINI","date":"1 octobre 2009","format":false,"excerpt":"Voil\u00e0 un petit panorama de l'utilisation des fonctionnalit\u00e9s XML de MySQL. Comme nous l'avons vu, g\u00e9n\u00e9rer le r\u00e9sultat d'une requ\u00eate au format XML reste tr\u00e8s simple avec le client texte mysql, idem pour la g\u00e9n\u00e9ration d'une sauvegarde (mysqldump). De plus, bien que n'\u00e9tant pas un base de donn\u00e9es XML, ont\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":227,"url":"https:\/\/dasini.net\/blog\/2008\/11\/27\/mysql-server-5130-ga-release\/","url_meta":{"origin":713,"position":3},"title":"MySQL Server 5.1.30 GA release","author":"Olivier DASINI","date":"27 novembre 2008","format":false,"excerpt":"MySQL 5.1 est enfin disponible pour la production","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":673,"url":"https:\/\/dasini.net\/blog\/2009\/07\/17\/utiliser-xml-avec-mysql-5-1-part-15\/","url_meta":{"origin":713,"position":4},"title":"Utiliser XML avec MySQL 5.1 (part 1\/5)","author":"Olivier DASINI","date":"17 juillet 2009","format":false,"excerpt":"MySQL avec son mod\u00e8le relationnel et XML avec son approche hi\u00e9rarchique ont en commun la vocation d'organiser et de structurer des ensembles de donn\u00e9es. En regardant de plus pr\u00e8s, ces technologies peuvent offrir des solutions compl\u00e9mentaires : * MySQL s'adapte \u00e0 merveille \u00e0 la gestion de syst\u00e8mes d'informations \u00e9ventuellement lourds\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":334,"url":"https:\/\/dasini.net\/blog\/2008\/12\/13\/les-nouveautes-de-mysql-51-part-45\/","url_meta":{"origin":713,"position":5},"title":"Les nouveaut\u00e9s de MySQL 5.1 &#8212; (part 4\/5)","author":"Olivier DASINI","date":"13 d\u00e9cembre 2008","format":false,"excerpt":"Le moteur de stockage CSV n'est pas une vraie nouveaut\u00e9. Il est disponible depuis MySQL 4.1.4 (MySQL 5.1 pour M.S. Windows). Sa particularit\u00e9 est de stocker les donn\u00e9es dans un fichier texte au format CSV (Comma Separated Values) o\u00f9 les donn\u00e9es sont s\u00e9par\u00e9es par une virgule. Les avantages sont multiples,\u2026","rel":"","context":"Dans &quot;MySQL&quot;","block_context":{"text":"MySQL","link":"https:\/\/dasini.net\/blog\/category\/mysql\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/713","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/comments?post=713"}],"version-history":[{"count":5,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/713\/revisions"}],"predecessor-version":[{"id":719,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/posts\/713\/revisions\/719"}],"wp:attachment":[{"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/media?parent=713"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/categories?post=713"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dasini.net\/blog\/wp-json\/wp\/v2\/tags?post=713"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}