Skip to content

Filtrer sur un critère (autres exemples) – N°10/XXX

15/03/2010

On a vu dans le billet n°9 une utilisation des crochets [ ] pour indiquer une condition, permettant de ne prendre qu’une partie d’un ensemble de nœuds.

Exemple 1 : base de revues

Imaginons que vous alimentez une base de revues, permettant un export XML (une base SQL est facilement exportable en XML avec phpMyAdmin).

Imaginons que l’export XML est de cette forme (je ne vous donne pas un fichier XML mais la structure de l’arbre. Logiquement ce devrait être équivalent pour vous).

Donc une balise racine <revues>, dont dépendent n revues avec trois éléments : le titre, l’URL et le statut (si on a gardé une revue dans la base, tout en s’étant désabonné).

Si on veut générer une liste lisible (en HTML, donc), limitée aux revues « actives », on peut écrire une feuille XSL qui ne prendra en compte que les revues concernées :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head><title>Liste de revues actives</title></head>
<body>
<ul>
<xsl:for-each select="//revue[statut='actif']">
<li>
<xsl:value-of select="titre"/><br/>
<xsl:value-of select="url"/>
</li>
</xsl:for-each>
</ul>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Notez bien que si je fais un test sur une valeur textuelle (<statut>actif</statut>), la valeur attendue doit être entre guillemets simples : select="//revue[statut='actif'].

Des guillemets simples, parce que des guillemets doubles fermeraient l’attribut select="".

Naturellement, si vos revues contiennent une indexation sujet, vous pourrez limiter aussi la liste aux revues dont le sujet est sciences, informatique ou ufologie.

Exemple 2 : Récupération d’items avec chaînes de caractères

Souvent, on a besoin que le test porte sur une partie de la chaîne.

Ainsi, dans l’exemple des revues ci-dessus, un certain nombre de titres seront hébergés sur Science Direct. Leur point commun ? L’URL contient la chaîne de caractères ‘sciencedirect.com’.

Je ne pourrai donc pas écrire <xsl:for-each select="//revue[url='sciencedirect.com']">, car cela signifie une correspondance exacte. Disons plutôt que je peux l’écrire, mais que le processeur XSL ne trouvera aucune correspondance.

La condition doit être que la chaîne de caractère globale dans l’url contient ‘sciencedirect.com’. Il y a une fonction contains(chaîne globale,sous-chaîne).

Voilà ce que ça donne :

<xsl:for-each select="//revue[contains(url,'sciencedirect.com')]">

Au sein du noeud <revue>, je cherche si le noeud enfant url contient la chaîne sciencedirect.com.

Pour ma part, j’ai eu un peu de mal au début à comprendre cette syntaxe qui ne correspond pas au langage naturel : on attendrait plutôt select="//revue[url contains('sciencedirect.com')"] ou quelque chose comme ça. Mais non…

Exercice 1 : filtre sur contains

Continuons à imaginer le fichier XML de périodiques électroniques décrit ci-dessus (je ne créerai pas ce fichier pour vous, je n’ai pas de données sous la main pour ça).

Il faut écrire un fichier XSL qui extraie la liste des titres (sous forme de liste à puces) dont l’URL est en https://

Voici le début et la fin, avec le milieu en blanc.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<html>
<head><title>Liste des revues en https://</title></head&gt;
<body>
<h1>Liste des revues en "https://"</h1>

…………………..

</body>
</html>
</xsl:template>
</xsl:stylesheet>

Exercice 2 : l’inverse

Cela peut correspondre à un réel besoin : on peut supposer que dans ce fichier, résultat d’un export d’une base de données, certaines URL ont été mal rentrées : on trouve donc des http://www.sciencedirect.com/etc au lieu de http://www.sciencedirect.com/etc, si bien que quand l’internaute clique dessus il tombe sur un message d’erreur.

Il faut donc extraire les titres des revues actives (sous forme de liste à puces) où l’URL ne contient pas « http ».

Donc il faut nier la condition contains, c’est-à-dire définir un contains(), et obtenir la condition inverse. Là encore, STFW 🙂

Advertisements
9 commentaires
  1. 15/03/2010 12:36

    @Lully Je refuse de faire cet exercice à cause de l’exemple pris :
    l’éditeur (ou la plateforme) dont-on-doit-citer-le-nom !
    Je trouve de plus en plus inquiétant que les bibliothécaires
    quand ils parlent de revues numériques n’aient que ce nom là en tête !

    Qu’Ebsco ait réussit à faire passer le nom de son logiciel AtoZ comme
    un nom commun peut être vu comme une jolie réussite commerciale.

    Que des professionnelles ne connaissent plus qu’une seule plateforme
    de revues numériques me semble très grave …

    Sinon
    peut être qu’un select="//revue[starts-with(url,'https')]"
    pourrait convenir pour le 1

    et que select="//revue[not(starts-with(url,'https'))]"
    pourrait convenir pour le 2

  2. 15/03/2010 12:50

    @Dominique : je ne partirai pas dans ce genre de débat !
    Pour les deux réponses proposées :
    Elles s’appuient sur starts-with() plutôt que sur contains() : pourquoi pas ? mais ce n’était pas nécessaire puisque la fonction contains(), objet du présent billet, permet d’y satisfaire.

    La réponse pour le 1 fonctionnera.

    La réponse pour le 2 ne correspond pas à la question. C’est très bien pour la fonction not(). Mais en l’occurrence, vous obtiendrez toutes les revues dont le champ URL commence par http:// (puisque une URL en http:// ne commence par par https…).
    Or l’objectif est de repérer les URL mal rentrées, dans lesquelles on aurait oublié d’indiquer le protocole : càd les URL en « amerika.revues.org » ou en « www.springerlink.com/content/111812/ ».

  3. 15/03/2010 15:29

    @Lully
    pour le 2 en effet ma réponse ne convennait pas à la question posée !
    et :
    select="//revue[not(starts-with(url,'http://')) or not(starts-with(url,'https://'))]"
    pour inclure les 2 protocoles et le starts-with pour repérer les blancs mis devant http
    comme par exemple " http://www.cairn.info/revue.php?ID_REVUE=ACO"
    (c’est fout ce qu’on trouve comme exemples de revues numériques !)

  4. 15/03/2010 21:41

    @Dominique : oui, c’est très bien
    [au fait, pour les autres : la fonction starts-with, comme son nom l’indique, fait un test sur le début de la chaîne de caractères définie dans le premier argument (en l’état, le premier argument est le noeud <url>, et le test de début de chaîne est ce qui est entre guillemets simples)]
    Mais en fait pour éviter le or, il suffit alors de faire un test
    select="//revue[not(starts-with(url,'http'))]", puisque dans "https", il y a "http".

  5. 16/03/2010 14:17

    @Lully Mais en fait pour éviter le or, il suffit alors de faire un test
    select="//revue[not(starts-with(url,'http'))]", puisque dans "https", il y a "http".

    oui,
    c’était simplement pour faire un test « un peu plus » complet sur la syntaxe du protocole
    (pour débusquer les http/www.molecularcytogenetics.org/home par exemple)

    (c’est fou ce qu’on trouve comme exemples de revues numériques !)
    (je le redis, c’est pas pour insister, mais pour corriger la faute)

  6. 16/03/2010 16:52

    Mouais… De manière générale (et par expérience personnelle — mais vous en avez une aussi !), quand on administre une base de revues, on cherche de manière systématique des erreurs constatées plusieurs fois par hasard : on ne cherche pas au hasard des erreurs jamais trouvées
    (mais manifestement vous et moi n’avons pas rencontré les mêmes erreurs !)

Trackbacks

  1. Correction de l’exercice 10 « Bibliothèques [reloaded]
  2. Techno-fil (21/03/10) « pintiniblog
  3. Série XSL : Petite synthèse des billets passés (2) « Bibliothèques [reloaded]

Les commentaires sont fermés.

%d blogueurs aiment cette page :