2012-09-03 10 views
12

ho, per esempio, il prossimo query XPath:Javascript: usare XPath in jQuery

//div[span="something"]/parent::div/child::div[@class=\"someClass\"] 

voglio usare questa query XPath in JavaScript:

return $("a:contains('Fruits')").mouseover(); 

ho provato questo:

return $("div[span=\"something\"]/parent::div/child::div[@class=\"someClass\"]").mouseover(); 

Ma non ha funzionato. C'è un'altra semantica per le query XPath al fine di usarli in JavaScript?

risposta

10

È possibile riscrivere le query XPath come selettori CSS:

$('div:has(> div > span:contains(something)) > div.someClass'); 

È possibile ottenere lo stesso effetto parent:: mediante il selettore :has pseduo per selezionare un elemento in base ai suoi figli: div.foo:has(> div.bar) selezionerà tutti div elementi con classe foo che hanno un figlio div con classe bar. Questo è equivalente a div[@class="bar"]/parent::div[@class="foo"].

Vedi:

si potrebbe forse avvicinarsi a questo in molti altri modi utilizzando varie combinazioni jQuery's DOM traversal methods. Ad esempio, questo sarebbe una traduzione molto diretta della query XPath:

$('div:has(> span:contains(something))') // //div[span="something"] 
    .parent('div')      // /parent::div 
    .children('div.someClass');   // /child::div[@class="someClass"] 

Vale la pena notare che div.someClass in CSS non è l'esatto equivalente di div[@class="someClass"] in XPath. Il CSS corrisponderà a <div class='foo someClass bar'>, ma xpath no. Vedi Brian Suda's article on parsing microformats with XSLT per maggiori dettagli.

+0

è il supporto CSS della clausola genitore :: div? –

+0

La traduzione di xpath in CSS è sbagliata, l'ho corretta e ho spiegato come viene riprodotto 'parent :: div'. – georgebrock

1

io non sono sicuro circa la clausola parent::div, ma senza di esso dovrebbe apparire in questo modo:

$('div[span="something"] div.someClass'); 
+1

in XPath 'div [ span = "qualcosa"] 'seleziona gli elementi' div' con uno 'span' figlio che ha il valore di testo' qualcosa', non cerca un attributo 'span'. Penso che lo stiate mescolando con (molto simile all'aspetto) 'div [@ span =" something "]'. Vedi esempi: http://www.w3.org/TR/xpath/#path-abbrev – georgebrock

2

Non c'è Implementazione cross-browser per quanto ne so. C'è un xpath plugin per jQuery che dice che è ancora in sviluppo.

Oltre a ciò, esiste un'implementazione JavaScript puro creata da Google della specifica XPath DOM Level 3 denominata wicked-good-xpath che è buona.

4

Come coautore di Wicked Good XPath, lo consiglio sicuramente per il supporto XPath cross browser (su documenti HTML, è possibile provare a utilizzarlo con documenti XML ma il supporto è incompleto).

Accogliamo con favore qualsiasi tipo di test di correttezza/benchmark delle prestazioni sulla nostra libreria. Durante lo sviluppo, la libreria è stata testata su IE 7 fino a 10 più il browser Android 2.2 che non ha il supporto nativo per XPath.

23

Si potrebbe aggiungere i risultati di una valutazione XPath esistente per una selezione jQuery, ho buttato insieme questa estensione jQuery che sembra fa tutto per te.

Esempio utilizzo:

$(document).xpathEvaluate('//body/div').remove() 

Ecco il componente aggiuntivo.

$.fn.xpathEvaluate = function (xpathExpression) { 
    // NOTE: vars not declared local for debug purposes 
    $this = this.first(); // Don't make me deal with multiples before coffee 

    // Evaluate xpath and retrieve matching nodes 
    xpathResult = this[0].evaluate(xpathExpression, this[0], null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null); 

    result = []; 
    while (elem = xpathResult.iterateNext()) { 
     result.push(elem); 
    } 

    $result = jQuery([]).pushStack(result); 
    return $result; 
} 
+0

Questa è una soluzione eccellente, grazie. – tenfour

+0

Grazie per quel fantastico codice :) Mi ha davvero aiutato. – interstellarDust

+0

funziona proprio perfetti – TechDog

1

se si desidera selezionare un elemento all'interno di un iframe, dalla finestra principale, si dovrebbe cambiare secondo parametro di evaulate() per elemento del documento di iframe, come:

var iFrameDocument = $('iframe#myPage').get(0).contentWindow.document; 
xpathResult = this[0].evaluate(xpathExpression, iFrameDocument, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);