2009-05-19 10 views
2

J'ai un document XHTML, et je veux sélectionner la seule table avec class = "index". Si je comprends bien, l'axe descendant sélectionnera tous les nœuds directement et indirectement en descendant du nœud actuel, alors voici ce que j'ai.Sélection d'une table spécifique avec XPath

//descendant::table[@class="index"] 

Il ne semble pas fonctionner lorsqu'il est testé avec xmlstarlet. Mon outil est-il cassé ou l'expression XPath est-elle incorrecte?

+1

Si vous entrez postez exemple, nous pourrions savoir à coup sûr si l'outil est cassé. (Par exemple, vous devez peut-être utiliser un préfixe d'espace de nom.) Une note rapide, // descendant :: est redondante. Dans ce cas, utilisez soit/descendant :: table (juste une barre oblique) ou simplement // table. "//" est un raccourci pour "/ descendant-or-self :: node() /" –

+0

metacritic.com/film/highscores.shtml est un exemple, mais il doit être passé par Tidy et d'autres réglages avant qu'il ne soit XSLT prêt. – jldugger

+0

Les réglages incluent-ils l'ajout de la déclaration d'espace de noms XHTML? Dans XPath, vous devez déclarer l'espace de noms (et utiliser un préfixe dans votre expression) si vous souhaitez sélectionner des nœuds par nom qui utilisent un espace de noms. –

Répondre

2

Sur la base de votre page exemple (metacritic.com/film/highscores.shtml), je dirais que vous devez utiliser:

//TABLE[@CLASS="index"] 
(or /descendant::TABLE[@CLASS="index"]) 

En effet, le tableau avec un indice de classe est écrite en majuscules sur votre page d'exemple (XML et XPath sont sensibles à la casse).

Cela fonctionnera si vous ciblez une page spécifique, mais deviendra probablement un problème si des pages différentes utilisent des cas différents pour les mêmes balises html.

Ensuite, vous aurez besoin d'une abomination Donc, comme

//TABLE[@CLASS="index" or @class="index" or @Class="index" or ...] 
|//table[@CLASS="index" or @class="index" or ...] 
|... 

vous aurez probablement besoin de continuer à utiliser Tidy avant l'extraction d'informations ou passer à un outil qui est spécialisé pour gratter HTML (au lieu de XPath)

+0

en effet, Tidy fait partie du processus, mais il se base sur un HTML mal formaté qui place un td dans un formulaire. J'ai déjà une version presque basée sur BeautifulSoup et uTidy; comprendre comment réparer la forme laide via Tidy ou Sed est la prochaine étape, je pense. – jldugger

3

Je pense //table[@class="index"] est ce que vous voulez

1

Oui, l'axe descendant sélectionne tous les noeuds descendant du noeud contextuel. Mais la clé ici est le nœud de contexte. Par exemple, descendant::span récupérera tous les descendants span du nœud actuel. Dans la même veine, descendant::* récupérera tous les éléments descendants du nœud actuel.

Si vous devez faire correspondre la table ainsi que les enfants, le XPath fourni belles œuvres au cours de mon essai:

//descendant::table[@class="index"] 

... sélectionne le tableau lui-même et childNodes.

Si vous ne devez faire correspondre les enfants de la table, tout d'abord correspondre au nœud que vous voulez puis ses descendants correspondre:

//table[@class="index"]/descendant::* 

.. ne sélectionne que les nœuds enfants du tableau.

0

utiliser ce code

let $info :=($p//descendant::TABLE[@class="index"]) 
     return $info 
Questions connexes