Различные результаты выбора элементов HTML с XPath в Firefox и Internet Explorer - PullRequest
6 голосов
/ 07 октября 2008

Я пытаюсь выбрать определенный элемент HTML в документе, для Firefox я просто использую:

xpathobj = document.evaluate(xpath, document, null,
               XPathResult.FIRST_ORDERED_NODE_TYPE, null);

, который работает нормально. Однако, когда я пытаюсь использовать IE эквивалентный:

xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.load(document);
xmlDoc.setProperty("SelectionLanguage", "XPath");
xpathobj = xmlDoc.selectNodes(xpath);

Мне не возвращают объект. Итак, мой вопрос, есть ли простой способ использовать XPath, чтобы получить элемент, который я хочу в IE? Используемый мной XPath выглядит как

/HTML/BODY/DIV[9]/DIV[2]

Ответы [ 10 ]

3 голосов
/ 02 февраля 2010

Проблема может заключаться в том, что в IE5 + [1] на самом деле [2] в FF. Microsoft единолично решила, что нумерация должна начинаться с [0], а не с [1], как указано в w3c.

3 голосов
/ 07 октября 2008

Взгляните на http://dev.abiss.gr/sarissa/ проект. Они перенесли большинство связанных с XML API в IE. В противном случае это действительно также легко реализовать. Проблемы, которые вам нужно решить, будут заключаться в следующем: сериализация HTML в действительный XML, синхронизация результата запроса XMLDOM XPath с оригинальным HTMLDOM. Насколько мне известно, они сделали это в своей библиотеке, однако его производительность могла бы быть лучше.

1 голос
/ 20 июля 2010

В коде oly1234 есть некоторые ошибки, которые я пытаюсь исправить следующим образом:

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;
}
1 голос
/ 08 октября 2008

Привет, хорошо, в конце концов, я придумал свое собственное хитрое решение, любые предложения по его улучшению будут высоко оценены. Он использует некоторые функциональные возможности прототипа:

Работает в IE5 + с xpath вида "/ HTML / BODY / DIV [9] / DIV [2]"

функция getXPathElement (xpath, element) {

//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++;
}

}

функция 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;

}

Спасибо всем за помощь, так или иначе я узнал немало о различных фреймворках javascript.

0 голосов
/ 20 июля 2010

Я не могу найти простое и распространенное решение, вы можете написать пользовательскую функцию, чтобы реализовать немного xpath, но трудно получить полную версию в Internet Explorer 6 или более поздней версии ....

0 голосов
/ 01 мая 2009

Другая реализация JavaScript W3C Dom Level 3 XPath может быть найдена в Source Forge . Но, похоже, не активен.

0 голосов
/ 08 октября 2008

Я бы немного беспокоился об использовании xml, как это, так как вы не можете быть уверены, какая версия (если есть) XML DLL у человека. По-прежнему есть компании, использующие IE5.0 в массовом порядке, а в 5.5 была реализована XML-реализация с очень трудными условиями.

0 голосов
/ 08 октября 2008

Вместо того, чтобы делать

xmlDoc.load(document); 

попробовать

xmlDoc.loadXML(document.body.outerHTML)

Это действительно будет работать, только если ваш HTML-документ отформатирован в соответствии со стандартами XHTML. Кроме того, тег BODY будет корневым узлом, поэтому вам придется изменить XPATH на "/ BODY / DIV [9] / DIV [2]"

0 голосов
/ 07 октября 2008

jQuery реализует совместимое с браузером подмножество селекторов xPath с плагином . Ваш пример "/ HTML / BODY / DIV [9] / DIV [2]" должен работать в нем.

(редактировать - исправлено благодаря Сергею Ильинскому)

0 голосов
/ 07 октября 2008

Вы уверены, что X-Path реализован в вашей версии Internet Explorer? Как в: какую версию вы используете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...