Utilisez les fonctions XPath intégrées
Dans le cadre du développement de l'un des cours de formation en ligne Altova, j'ai trié une liste de livres par auteur. J'ai constaté que le champ "auteur" contenait une chaîne de caractères représentant le nom complet de l'auteur, ce qui faisait que les livres étaient triés en fonction de la première lettre de cette chaîne, c'est-à-dire du prénom de l'auteur. Il n'était pas possible de corriger ce tri dans le cadre du cours, mais vous pouvez facilement extraire le nom de famille d'une chaîne de caractères et l'utiliser comme clé de tri en utilisant des fonctions XPath. Si vous utilisez ensuite les titres des livres comme clé de tri secondaire, vous rencontrerez un problème avec les titres qui commencent par "A", "An" ou "The". Je souhaite utiliser le titre comme clé de tri secondaire, mais en ignorant les articles définis ou indéfinis en début de titre.
![]()
Examinons la manière dont nous avons créé ce code XSLT. Cet article a été rédigé en utilisant XMLSpy comme plateforme, mais les mêmes expressions XPath peuvent être utilisées dans MapForce ou StyleVision pour obtenir des résultats similaires. Nous pouvons commencer avec une simple liste de livres en XML. Nous avons 4 livres, chacun avec des éléments "auteur" et "titre".
![]()
Un code XSLT pour créer une liste de livres ressemblerait à ceci :
![]()
Cela générera le résultat suivant :
![]()
Les livres sont générés dans l'ordre dans lequel ils apparaissent dans le fichier de données original. Si nous ajoutons l'élément xsl:sort à la boucle xsl:for-each, nous pouvons organiser notre résultat de différentes manières.
![]()
Cela générera une liste triée, mais pas correctement triée.
![]()
Le tri par l'auteur, considéré comme une chaîne de caractères, fait apparaître "Jules Verne" avant "Mark Twain". De même, "A Connecticut Yankee in King Arthur's Court" apparaît avant "Adventures of Huckleberry Finn". Nous souhaitons ignorer l'article indéfini "A" afin que "Adventures of Huckleberry Finn" apparaisse avant "A Connecticut Yankee in King Arthur's Court". Nous pouvons utiliser des expressions XPath pour extraire les clés de tri que nous souhaitons.
![]()
Examinons le code avant de regarder le résultat. Nous remplaçons "author" par "reverse(tokenize(author, ' '))[1]". La fonction "tokenize" divise la chaîne de caractères "author" en éléments en utilisant un espace simple comme séparateur. Ainsi, "Jules Verne" est divisé en "Jules" et "Verne". La fonction "reverse" inverse l'ordre de ces éléments, les transformant en "Verne" et "Jules". L'élément entre crochets sélectionne le premier élément de la liste, qui est "Verne". C'est cette valeur qui est utilisée dans la fonction xsl:sort pour organiser les livres. Ce n'est pas la solution idéale, mais elle fonctionne dans notre cas. Le titre semble complexe, mais la logique est simple. L'expression "tokenize(title, ' ')[1]" extrait le premier mot du titre. Ainsi, le premier test "if" est : "Le premier mot du titre est-il le mot "A" ?". Si c'est le cas, nous renvoyons la sous-chaîne du titre qui commence par sa troisième lettre, éliminant ainsi "A" et l'espace. Si le premier mot du titre n'est pas "A", nous devons effectuer un autre test pour voir si le premier mot du titre est "The". Si c'est le cas, nous utilisons la sous-chaîne du titre qui commence par son cinquième caractère, éliminant ainsi "The" et un espace. Si les deux tests échouent, nous transmettons simplement le titre tel quel comme clé de tri. Nous pourrions ajouter un autre test à notre code pour vérifier si le premier mot est "An", mais ce n'est pas nécessaire pour cet ensemble de données. En exécutant cette dernière transformation XSLT, nous obtenons le résultat suivant.
![]()
"Mark Twain" est maintenant en tête de liste, devant "Jules Verne". "Les Aventures de Huckleberry Finn" apparaît avant "La Célèbre Grenouille Sautillante du Comté de Calaveras" et "Un Américain du Connecticut à la cour du roi Arthur". Le problème de notre approche concernant la chaîne de caractères représentant l'auteur est que nous voulons que "Jules Verne" soit traité comme "Verne, Jules" pour le tri, afin que, si nous avions un livre de "Jimmy Verne", le système les considère comme des auteurs différents. Notre code ne le fait pas. L'utilisation de "concat(reverse(tokenize(author, ' '))[1], reverse(tokenize(author, ' '))[2])" permettrait de trier correctement "Jules Verne" et "Jimmy Verne", mais cette solution ne fonctionne qu'avec des noms de deux mots. Si un auteur avait un suffixe ("Martin Luther King, Jr.") ou plusieurs mots ("George Herbert Walker Bush"), le code échouerait. Il existe de nombreuses exceptions aux règles générales de classement alphabétique des noms, et le code permettant de prendre en compte toutes ces variantes dépasse le cadre de cet article. Ce que nous voulions montrer, c'était la capacité de manipuler des données XML en temps réel à l'aide d'expressions XPath. Nous n'avons pas toujours un contrôle total sur le format de nos sources de données, mais en utilisant la puissance des expressions XPath, nous pouvons transformer les données dans le format dont nous avons besoin. Une copie des fichiers utilisés dans ces exemples est disponible ici.