2012-09-03 7 views
12

que tienen, por ejemplo, la siguiente consulta XPath:Javascript: utilizar XPath en jQuery

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

quiero usar esta consulta XPath en JavaScript:

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

He intentado esto:

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

Pero no funcionó. ¿Hay alguna otra semántica para las consultas XPath para usarlas en JavaScript?

Respuesta

10

Se puede volver a escribir sus consultas XPath como selectores CSS:

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

Se puede lograr el mismo efecto que parent:: con el selector :has pseduo para seleccionar un elemento en base a sus hijos: div.foo:has(> div.bar) seleccionará todos div elementos con clase foo que tienen un hijo div con clase bar. Esto es equivalente a div[@class="bar"]/parent::div[@class="foo"].

Ver:

que probablemente se podría abordar esto en varias otras maneras usando varias combinaciones jQuery's DOM traversal methods. Por ejemplo, esto sería una traducción muy directa de la consulta XPath:

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

Vale la pena señalar que en div.someClass CSS no es el equivalente exacto de div[@class="someClass"] de XPath. El CSS coincidirá con <div class='foo someClass bar'>, pero el xpath no lo hará. Ver Brian Suda's article on parsing microformats with XSLT para más detalles.

+0

¿CSS es compatible con la cláusula parent :: div? –

+0

La traducción de mi xpath a CSS fue incorrecta, la corrigí y explico cómo se reproduce 'parent :: div'. – georgebrock

1

No estoy seguro acerca de la cláusula parent::div, pero sin que se debería tener este aspecto:

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

En XPath 'div [ span = "algo"] 'selecciona elementos' div' con un 'span' niño que tiene el valor de texto' something', no busca un atributo 'span'. Creo que lo estás mezclando con el (muy parecido) 'div [@ span =" something "]'. Ver ejemplos: http://www.w3.org/TR/xpath/#path-abbrev – georgebrock

2

No hay Implementación entre navegadores, hasta donde yo sé. Hay un xpath plugin para jQuery que dice que todavía está en desarrollo.

Aparte de eso, existe una implementación de JavaScript pura de Google propia de la especificación XPath DOM Level 3 llamada wicked-good-xpath que es buena.

4

Como coautor de Wicked Good XPath, ciertamente lo recomiendo para el soporte de XPath para navegadores cruzados (en documentos HTML, puede intentar usarlo con documentos XML pero la compatibilidad es incompleta).

Le damos la bienvenida a cualquier tipo de punto de referencia de prueba/rendimiento de corrección en nuestra biblioteca. Durante el desarrollo, la biblioteca se ha probado en IE 7 a 10 más el navegador Android 2.2 que no tiene soporte XPath nativo.

23

Puede agregar los resultados de una evaluación existente de XPath a una selección de jQuery, armé esta extensión de jquery que parece que lo hace todo para usted.

Ejemplo de uso:

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

Aquí está el complemento.

$.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

Esta es una excelente solución, gracias. – tenfour

+0

Gracias por ese código increíble :) Realmente me ayudó. – interstellarDust

+0

Funciona simplemente perfecto – TechDog

1

si desea seleccionar un elemento dentro de un iframe, desde la ventana padre, usted debe cambiar segundo parámetro de evaulate() para elemento de documento de marco flotante, como:

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