@neo, l'expression XPath vous listez ne fonctionne pas quand je le tester. Essayez un ensemble de données différentes et vous verrez:
<root>
<item>
<d>2003-05-30T09:00:00</d>
</item>
<item>
<d>2002-05-30T09:00:00</d>
</item>
<item>
<d>2005-05-30T09:00:00</d>
</item>
</root>
Votre XPath produit 2003-05-30T09:00:00
, ce qui est évidemment pas le maximum.
Et il est logique que cela ne fonctionne pas, car les axes suivants-sibling :: et following-sibling :: dans les fonctions translate() ne donneront qu'un seul frère. Vous essayez d'effectuer une comparaison générale (ensemble) sur tous les frères et soeurs de chaque axe, mais le premier argument de translate() doit être converti en une chaîne, avant que l'opérateur de comparaison général ait une chance de faire son truc. Converting a nodeset to a string ignores all nodes except the first one in document order.
En outre, translate(./d, 'TZ:-', '.')
vous donne des résultats comme 2003.05.30.09.00.00
. Ce n'est pas un nombre valide, au-delà du '5'. Vos données de test ne fonctionnent que parce que les années sont toutes différentes. Vous obtiendriez de meilleurs résultats avec translate(./d, 'TZ:-', '')
ce qui donnerait 20030530090000
. Alejandro dit qu'il n'est pas possible de faire cela dans XPath 1.0, et il a peut-être raison. Essayons, et peut-être que nous apprendrons quelque chose même si nous n'y parvenons pas.
Ensuite, j'essaierais d'utiliser la comparaison générale en dehors de la fonction de traduction, afin de pouvoir comparer des ensembles de nœuds entiers. Quelque chose comme cette tentative naïve:
/root/item[
not(following-sibling::item[
translate($current/d, 'TZ:-', '') <= translate(./d, 'TZ:-', '')])
and not(preceding-sibling::item[
translate($current/d, 'TZ:-', '') <= translate(./d, 'TZ:-', '')])]
Cependant elle est incomplète comme le montre le courant de $ pseudo-variable, qui est censé se référer à l'élément le plus extérieur, celui qui est le nœud de contexte extérieur tous les prédicats. Malheureusement, XPath 1.0 ne nous permet pas de faire référence à ce contexte externe lorsqu'un autre contexte a été poussé sur la pile par un prédicat interne.(Il semble que certaines implémentations de XSLT, comme MSXML, vous permettent de faire cela en utilisant une fonction étendue comme current(1)
, mais je ne trouve pas d'informations à ce sujet pour le moment. Une solution XPath, et current()
n'est pas XPath.)
À ce stade, je vais être d'accord avec Alejandro que c'est impossible en XSLT 1.0 standard pur.
Si vous spécifiez l'environnement dans lequel vous utilisez XPath, par ex. XSLT, ou Javascript, ou XQuery, nous pouvons probablement vous suggérer un moyen efficace d'obtenir ce dont vous avez besoin. Si c'est XPath 2.0, Alejandro a votre réponse.
Si vous avez XQuery 1.0, il devrait soutenir XPath 2.0, vous pouvez utiliser la solution d'Alejandro, avec doc() pour accéder à votre document XML d'entrée:
max(doc("myInput.xml")/root/item/d/xs:dateTime(.))
Fonctionne très bien, j'aime beaucoup cette syntaxe, voir aussi mon commentaire sur l'autre réponse. – letmaik
@neo: Je suis content que cela vous ait aidé. Maintenant que vous savez que vous avez XQuery 1.0 et XPath 2.0, vous trouverez beaucoup d'améliorations de XPath 1.0: dans ce cas non seulement 'fn: max' mais aussi la possibilité d'utiliser les expressions comme étape finale dans le chemin. J'ai aussi réessayé ta question. –