2010-12-10 45 views
0

J'aimerais sélectionner un élément qui n'a pas d'enfant d'un type particulier, par exemple:CSS Selectors: élément select où (parent | enfants) ne correspond pas à X

tous <li> éléments qui n'ont pas <table class="someclass"> enfants, je voudrais sélectionner uniquement l'élément parent, pas les enfants qui ne correspondent pas à la table.

Sur une note similaire, je voudrais faire correspondre les éléments dont les parents ne correspondent pas X, par exemple: tous <li> éléments qui ne sont pas des descendants de <table class="someclass">.

J'utilise python, et le cssselect de lxml.

Merci!

+2

Je pense qu'aucun de vos conditions peuvent être remplies à la norme Sélecteurs CSS. – Gumbo

Répondre

0

Je ne pense pas que les sélecteurs CSS ont « tout sauf » sélection, donc vous ne pouvez le faire de cette façon. Peut-être que vous pouvez le faire avec XPaths. qui sont plus flexibles, mais même alors vous obtiendrez des expressions de chemin très complexes et obtuses.

Je vous recommande d'obtenir simplement tous les éléments <li>, de passer par chaque enfant elemnts, et de le passer si l'un des enfants est une table. Ce sera facile à comprendre et à gérer, facile à implémenter, et à moins que vos exigences de performance soient vraiment extrêmes et que vous ayez à traiter des dizaines de milliers de pages par seconde, ce sera Fast Enough (tm).

Keep it simple.

1

Le CSS3 :not selector vous obtiendrez en partie là. Malheureusement, there is no parent selector de sorte que vous ne pouvez pas sélectionner un élément en fonction des caractéristiques de ses enfants.

Pour votre première question que vous devez faire explicitement la traversal:

# All <li> elements who have no <table class="someclass"> children 
[e.getparent() for e in CSSSelector('li > table:not(.someclass)')(html)] 

# To make it unique if there could be multiple acceptable child tables 
set(e.getparent() for e in CSSSelector('li > table:not(.someclass)')(html)) 

# If there could be empty <li> 
set(itertools.chain(
    (e.getparent() for e in CSSSelector('li > table:not(.someclass)')(html)), 
    CSSSelector('li:empty')(html) 
)) 

sélecteurs CSS seul peut gérer votre deuxième question:

# All <li> elements who are not descendents of <table class="someclass"> 
CSSSelector(':not(table.someclass) li')(html)