Я пытаюсь выбрать конкретный элемент 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]
Вы уверены, что X-Path реализован в вашей версии Internet Explorer? Например: какую версию вы используете?
Взгляните на проект http://dev.abiss.gr/sarissa/. Они перенесли большинство API, связанных с XML, в IE. В противном случае это действительно также легко реализовать. Проблемы, которые вам необходимо решить, будут следующими: сериализация HTML в действительный XML, синхронизация результата запроса XMLDOM XPath с исходным HTMLDOM. Насколько мне известно, они сделали это в своей библиотеке, однако производительность могла бы быть лучше.
jQuery реализует кроссбраузерно совместимое подмножество селекторов xPath с подключаемым модулем. Ваш пример "/ HTML / BODY / DIV [9] / DIV [2]" должен работать в нем.
(править - исправлено спасибо Сергею Ильинскому)
Вместо того, чтобы делать
xmlDoc.load(document);
пытаться
xmlDoc.loadXML(document.body.outerHTML)
Это действительно будет работать, только если ваш HTML-документ отформатирован в соответствии со стандартами XHTML. Кроме того, тег BODY будет корневым узлом, поэтому вам придется изменить XPATH на "/ BODY / DIV [9] / DIV [2]"
Я бы немного побеспокоился об использовании подобного xml, так как вы не можете быть уверены, какая версия (если есть) XML DLL у человека. Все еще есть компании, использующие IE5.0 в массовом порядке, а в 5.5 была особенно гибкая реализация XML.
Привет, в конце концов, я придумал свое собственное хитрое решение, любые предложения по его улучшению были бы очень признательны. Он использует некоторые функции прототипа:
Работает в IE5 + с xpath в форме "/ HTML / BODY / DIV [9] / DIV [2]"
function 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++;
}
}
function getXPathElementByIndex (потомки, 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.
Другую реализацию W3C Dom Level 3 XPath в JavaScript можно найти на Source Forge. Но не проявляет активности.
Проблема может заключаться в том, что в IE5 + [1] на самом деле [2] в FF. Microsoft единолично решила, что нумерация должна начинаться с [0], а не с [1], как указано w3c.
Я не могу найти простое и распространенное решение, вы можете написать собственную функцию для реализации небольшого количества xpath, но это сложно сделать в Internet Explorer 6 или более ранней версии ....
В коде 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;
}
jQuery НЕ реализует XPath. Он реализует очень простую функцию выбора пути (что составляет около 0,01% от XPath).