3
votes

Pourquoi normalize-space (text ()) ne fonctionne-t-il pas avec un élément enfant précédent?

Il ne fait aucun doute que c'est extrêmement basique, mais ça ne "cliquera" pas pour moi, malgré les recherches que j'ai faites jusqu'à présent. Compte tenu des deux exemples HTML suivants:

Exemple 1

<div _ngcontent-c42="" class="row facet-panel ng-star-inserted">
    <div _ngcontent-c42="" class="facet-panel-header brand-pointer" data-target="#ft5" data-toggle="collapse">
        <span _ngcontent-c42="" class="icon-plus ng-star-inserted" data-target="#ft5" data-toggle="collapse">
        </span> 
        Locatie
    </div>
    <div _ngcontent-c42="" class="collapse" id="ft5">
    </div>
</div>

Exemple 2

<div _ngcontent-c35="" class="row facet-container ng-star-inserted">
    <div _ngcontent-c35="" class="searchresult-header">
        Locatie
    </div>
</div>

Maintenant, j'ai le morceau suivant de xpath:

//div[.//div[normalize-space(text())='Locatie ']]

Selon d'autres questions et sites Web sur xpath, text () sélectionne des nœuds de texte descendant directement du nœud sur lequel nous recherchons. Par conséquent, dans l'exemple n ° 1, j'espère récupérer le premier élément "div" enfant. Cela se passe correctement: aucun problème.

J'attends le même résultat dans l'exemple n ° 2. Cependant, ce n'est pas le cas: apparemment l'élément "span" perturbe cette recherche spécifique. Lorsque je le supprime manuellement, je récupère avec succès l'élément "div" requis. Pourquoi la recherche est-elle interrompue? Le texte doit toujours être un enfant direct de l'élément div, peu importe si l'élément span est là ou non.

TLDR: Pourquoi l'élément "span" m'empêche-t-il de trouver le second " div "élément dans l'exemple n ° 2?


0 commentaires

3 Réponses :


0
votes

Cela peut avoir quelque chose à voir avec le texte / les espaces blancs (c'est bien au-dessus de ma note de salaire ...), car avec ce changement d'orientation, l'expression suivante semble fonctionner avec la plupart (pas tous) des testeurs xpath:

.//div[text()[contains(.,'Locat')]]


0 commentaires

2
votes

Je suppose que c'est parce que normalize-space (text ()) = 'Locatie'] a l'intention de vérifier le premier nœud de texte enfant (qui est en fait juste une chaîne vide ) pendant que vous devez vérifier le deuxième un:

//div[normalize-space(div)='Locatie']

Si vous avez besoin d'un XPath générique qui fonctionnera dans les deux cas, essayez

//div[.//div[normalize-space(text()[2])='Locatie']]


0 commentaires

2
votes

Comme Jason a répondu , c'est parce que la signature de normalize-space () fonction, à partir des spécifications:

Fonction : chaîne normaliser-espace ( chaîne ?)

Dans XPath 1.0, chaque fois qu'un argument de chaîne est nécessaire, le langage applique une conversion de type au moyen de string () fonction. D'après les spécifications:

Un ensemble de nœuds est converti en chaîne en renvoyant la valeur de chaîne de le nœud de l'ensemble de nœuds qui est le premier dans l'ordre des documents. Si la l'ensemble de nœuds est vide, une chaîne vide est renvoyée.

Ainsi, l'ensemble de nœuds résultant du test de nœud text () est réduit au premier nœud dans l'ordre du document , puis ce nœud est converti à sa string-value .

À cet égard, c'est lorsque les espaces blancs surveillent toujours que seuls les nœuds de texte viennent à remarquer: votre élément div a deux nœuds de texte:

//div[.//div/text()[normalize-space()='Locatie']]
Chaque fois que vous avez un balisage de contenu mixte, il est préférable d'utiliser la valeur de chaîne plutôt que les nœuds de texte.

Sinon, vous devez utiliser cette expression:

<div>
    <div>
        <!-- HERE ENDS THE FIRST --><span>
        </span> 
        Locatie
    <!-- HERE ENDS THE SECOND --></div>
    <div>
    </div>
</div>


1 commentaires

Plus 1 pour mentionner le contenu mixte.