web-dev-qa-db-fra.com

Comment savoir à l'aide de XPath si un élément est présent et non vide?

J'ai une entrée XML quelque chose sur cette ligne:

<Holding id="12">
    <Policy>
        <HoldingForm tc="1">Individual</HoldingForm>
        <PolNumber>848433</PolNumber>
        <LineOfBusiness tc="1">Life</LineOfBusiness>
        <CarrierCode>67644</CarrierCode>
    </Policy>
</Holding>

Ma manipulation sur ce XML dépend de si <PolNumber> (c'est un élément facultatif dans le schéma) a une valeur ou non. J'utilise l'évaluateur Mule 3.3 xpath pour ce faire et mon expression XPath ressemble à ceci:

<expression-filter expression="#[xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"/> 

Cela fonctionne bien tant que <PolNumber> l'élément est présent ou <PolNumber/> est un élément vide. Mais si <PolNumber> est absent, l'expression ci-dessus lève une exception.

J'ai essayé d'utiliser la fonction XPath boolean mais elle renvoie true pour <PolNumber/>. Existe-t-il une meilleure façon de vérifier si un élément est présent et non vide?

ÉDITER:

Ceci est la configuration du gestionnaire d'espace de noms dans ma configuration mule

<xm:namespace-manager includeConfigNamespaces="true">
    <xm:namespace prefix="acord" uri="http://ACORD.org/Standards/Life/2" />
    <xm:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/encoding/" />
</xm:namespace-manager>
20
Charu Khurana

tiliser:

boolean(//acord:Holding/acord:Policy/acord:PolNumber/text()[1])

cela produit true() si //acord:Holding/acord:Policy/acord:PolNumber a un premier enfant de nœud de texte, et false() sinon.

Notez: C'est plus efficace que de compter tous les enfants de nœuds de texte juste pour comparer le nombre à 0.

26

Vous pouvez utiliser boolean(...) pour vérifier s'il est vide, mais assurez-vous de regardez à l'intérieur l'élément.

boolean(//PolNumber/node())

Cela fonctionne également si d'autres nœuds sont contenus. Si vous souhaitez vous limiter aux nœuds de texte, remplacez node() par text(). Vous pourriez vouloir utiliser //text() à la place, alors la requête donnera également true pour les nœuds de texte à l'intérieur d'autres éléments enfants de <PolNumber/>.

11
Jens Erat

Que diriez-vous de expression="#[?xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"? Cela devrait fonctionner dans toutes les situations

2
user3190499

Qu'en est-il de l'utilisation de count pour obtenir le nombre de nœuds de texte:

<expression-filter
    expression="#[xpath('count(//Holding/Policy/PolNumber/child::text())') != 0]"/>
1
David Dossot

Je suis peut-être un peu en retard ici, mais les réponses sont un peu confuses. Celui-ci renvoie toujours false lorsque le texte est vide ou avec des espaces mais pas de caractères.

boolean//Holding/Policy/PolNumber/child/text()[normalize-space()]
0
Thomas Modeneis