Puis-je créer une valeur pour une balise manquante dans XPath ?
Question
J'ai une application qui extrait les données d'un fichier XML à l'aide de XPath.Si un nœud dans ce fichier source XML est manquant, je souhaite renvoyer la valeur « N/A » (un peu comme la fonction Oracle NVL).Le problème est que l'application ne prend pas en charge XSLT ;J'aimerais le faire en utilisant XPath et XPath uniquement.
Est-ce possible?
La solution
Cela peut être fait mais seulement si la valeur de retour lorsque le nœud existe est la valeur de chaîne du nœud, pas le nœud lui-même.Le XPath
substring(concat("N/A", /foo/baz), 4 * number(boolean(/foo/baz)))
renverra la valeur de chaîne du baz
élément s'il existe, sinon la chaîne "N/A".
Pour généraliser l’approche :
substring(concat($null-value, $node),
(string-length($null-value) + 1) * number(boolean($node)))
où $null-value
est la chaîne de valeur nulle et $node
l'expression pour sélectionner le nœud.Notez que si $node
évalue un ensemble de nœuds contenant plusieurs nœuds, la valeur de chaîne du d'abord Le nœud est utilisé.
Autres conseils
Réponse courte:Non.Une telle fonction a été envisagée et explicitement rejetée pour la version 2 de la spécification XPath (voir la version non normative Section Fonctions illustratives écrites par l'utilisateur).
Pour les nœuds vides, vous avez besoin
boolean(string-length($node))
(Vous pouvez omettre l'appel à number()
car le passage du booléen au nombre est implicite ici.)
Cela peut être fait avec XPath 1.0.Dis que tu as
<foo>
<bar/>
</foo>
Si vous voulez tester si foo
a un baz
enfant,
substring("N/A", 4 * number(boolean(/foo/baz)))
renverra "N/A" si l'expression /foo/baz
renvoie un ensemble de nœuds vide, sinon il renvoie une chaîne vide.
@jelovirt
Donc, si je comprends bien, nous concaténons la réponse par défaut et la valeur du nœud, puis prenons le sous-ensemble correct de la chaîne résultante en testant l'existence du nœud pour définir le décalage sur zéro ou sur la position juste après mon chaîne par défaut.C’est la déformation la plus perverse d’un langage que j’ai jamais vue.(Je l'aime!)
Pour clarifier ce que vous avez dit, cette approche fonctionne lorsque le nœud est manquant, pas lorsque le nœud est vide.Mais en remplaçant "number(boolean($node))" par "string-length($node)", cela fonctionnera plutôt sur des nœuds vides.