queryselector - xpath javascript
Diferentes resultados al seleccionar elementos HTML con XPath en Firefox e Internet Explorer (10)
¿Estás seguro de que X-Path está implementado en tu versión de Internet Explorer? Como en: ¿qué versión estás usando?
Intento seleccionar un elemento HTML específico en un documento, para Firefox solo uso:
xpathobj = document.evaluate(xpath, document, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null);
que funciona bien Sin embargo, cuando pruebo el equivalente de IE:
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.load(document);
xmlDoc.setProperty("SelectionLanguage", "XPath");
xpathobj = xmlDoc.selectNodes(xpath);
No recibo ningún objeto devuelto. ¿Entonces mi pregunta es una forma fácil de usar XPath para llegar al elemento que quiero en IE? El XPath que estoy usando parece
/HTML/BODY/DIV[9]/DIV[2]
Eche un vistazo al proyecto http://dev.abiss.gr/sarissa/ . Han migrado la mayoría de las API relacionadas con XML a IE. De lo contrario, también es fácil de implementar. Los problemas que necesitaría resolver serían: la serialización de HTML en XML válido, el resultado de la sincronización de la consulta XPath XMLDOM con HTMLDOM original. Que yo sepa, lo han hecho en su biblioteca, sin embargo, su rendimiento podría haber sido mejor.
jQuery implementa un subconjunto de selectores xPath compatible con varios navegadores con un complemento . Su ejemplo "/ HTML / BODY / DIV [9] / DIV [2]" debería funcionar en él.
(corregir - corregido gracias a Sergey Ilinsky)
En lugar de hacer
xmlDoc.load(document);
tratar
xmlDoc.loadXML(document.body.outerHTML)
Esto solo funcionaría si tu documento HTML está formateado según los estándares XHTML. Además, la etiqueta BODY sería el nodo raíz, por lo que tendría que cambiar su XPATH a "/ BODY / DIV [9] / DIV [2]"
Estaría un poco preocupado por el uso de xml como este, ya que no puede estar seguro de qué versión (si la hay) de la DLL XML que tiene una persona. Todavía hay empresas que usan IE5.0 por ahí en tropel, y 5.5 tuvo una implementación de XML especialmente sobria.
Hola, al final se me ocurrió mi propia solución dudosa, cualquier sugerencia sobre mejorarla sería muy apreciada. Hace uso de algunas funcionalidades prototipo:
Funciona en IE5 + con xpath de la forma "/ HTML / BODY / DIV [9] / DIV [2]"
función getXPathElement (xpath, elemento) {
//Specific to project, here i know that the body element will always have the id "top"
//but otherwise the element that is passed in should be first element in the xpath
//statement eg. /HTML/BODY/DIV the element passed in should be HTML
if(!element){
element = $("top");
var xpathArrayIndex = 3;
} else {
var xpathArrayIndex = 1;
}
//split the xpath statement up
var xpathArray = xpath.split("/");
var carryOn = true;
while(carryOn){
decendents = element.childElements();
//check to see if we are at the end of the xpath statement
if(xpathArrayIndex == xpathArray.length){
return element;
}
//if there is only one decendent make it the next element
if(decendents.size() == 1) {
element = decendents.first();
} else {
//otherwise search the decendents for the next element
element = getXPathElementByIndex(decendents, xpathArray[xpathArrayIndex]);
}
xpathArrayIndex++;
}
}
función getXPathElementByIndex (decendents, xpathSegment) {
var decendentsArray = decendents.toArray();
//seperate the index from the element name
var temp = xpathSegment.split("[");
var elementName = temp[0];
//get the index as a number eg. "9]" to 9
var elementIndex = +temp[1].replace("]", "");
//the number of matching elements
var count = 0;
//keeps track of the number of iterations
var i = 0;
while(count != elementIndex) {
//if the decendent''s name matches the xpath element name increment the count
if(decendentsArray[i].nodeName == elementName){
count++;
}
i++;
}
var element = decendentsArray[i - 1];
return element;
}
Gracias a todos por su ayuda, de cualquier forma aprendí bastante sobre varios frameworks de JavaScript.
Otra implementación de JavaScript de W3C Dom Level 3 XPath se puede encontrar en Source Forge . Pero no parece estar activo.
El problema puede ser que en IE5 + [1] es de hecho [2] en FF. Microsoft decidió únicamente que la numeración debería comenzar en [0] y no [1] según lo especificado por w3c.
Hay algunos errores en el código de oly1234. Trato de arreglarlo de la siguiente manera:
function getXPathElement(xpath, element){
if(!element){
element = document;
}
var xpathArray = xpath.split("/");
element = findXPathRoot(xpathArray[0],xpathArray[1],element);
for(var i=1; i<xpathArray.length; i++){
if(xpathArray[i].toLowerCase()=="html"){
continue;
}
if(!element){
return element;
}
element = getXPathElementByIndex(element.childNodes,xpathArray[i]);
}
return element;
}
function findXPathRoot(rootPath,htmlPath,element){
if(rootPath == ""&&htmlPath.toLowerCase() == "html"){
return element.documentElement;
}
return document.getElementsByTagName(rootPath)[0];
}
function getXPathElementByIndex(decendents, xpathSegment){
//seperate the index from the element name
var temp = xpathSegment.split("[");
var elementName = temp[0];
//get the index as a number eg. "9]" to 9
if(temp[1]){
var elementIndex = temp[1].replace("]", "");
}else{
var elementIndex = 1;
}
//the number of matching elements
var count = 0;
for(var i=0;i < decendents.length; i++){
if (decendents[i].nodeName.toLowerCase() == elementName.toLowerCase()) {
count++;
if(count==elementIndex){
return decendents[i];
}
}
}
return null;
}
No puedo encontrar una solución simple y común, puedes escribir una función personalizada para implementar un poco de xpath, pero es difícil de completar en Internet Explorer 6 o versión más baja ....