6

我正在尝试在文档中选择特定的 HTML 元素,对于我只使用的 Firefox:

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

效果很好。但是,当我尝试 IE equivilent 时:

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]
4

10 回答 10

3

看看http://dev.abiss.gr/sarissa/项目。他们已将大部分与 XML 相关的 API 迁移到 IE。否则它确实也很容易实现。您需要解决的问题是:将 HTML 序列化为有效的 XML,将 XMLDOM XPath 查询的结果与原始 HTMLDOM 同步。据我所知,他们已经在他们的库中完成了它,但是,它的性能可能会更好。

于 2008-10-07T11:31:49.257 回答
3

问题可能在于 IE5+ 中的 [1] 实际上是 FF 中的 [2]。Microsoft 完全决定编号应该从 [0] 而不是 w3c 指定的 [1] 开始。

于 2010-02-02T11:34:10.263 回答
1

嗨,最后我想出了我自己的狡猾的解决方案,任何关于改进它的建议都会非常感激。它利用了一些原型功能:

在 IE5+ 中使用“/HTML/BODY/DIV[9]/DIV[2]”形式的 xpath

函数getXPathElement(xpath,元素){

//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(后代,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 框架有所了解。

于 2008-10-08T12:25:24.687 回答
1

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;
}
于 2010-07-20T03:50:54.373 回答
0

我有点担心像这样使用 xml,因为您无法确定一个人拥有的 XML DLL 的版本(如果有的话)。仍然有公司成群结队地使用 IE5.0,而 5.5 有一个特别复杂的 XML 实现。

于 2008-10-08T08:55:49.990 回答
0

W3C Dom Level 3 XPath的另一个 JavaScript 实现可以在 Source Forge上找到。但似乎不活跃。

于 2009-05-01T11:13:57.357 回答
0

您确定在您的 Internet Explorer 版本中实现了 X-Path 吗?如:您使用的是什么版本?

于 2008-10-07T11:26:31.153 回答
0

jQuery 使用插件实现了跨浏览器兼容的 xPath 选择器子集。您的示例“/HTML/BODY/DIV[9]/DIV[2]”应该可以在其中工作。

(编辑 - 谢尔盖伊林斯基更正)

于 2008-10-07T11:58:36.987 回答
0

我找不到一个简单通用的解决方案,你可以编写自定义函数来实现一点 xpath 但在 internet explorer 6 或更低版本中很难完成......

于 2010-07-20T02:36:02.230 回答
0

而不是做

xmlDoc.load(document); 

尝试

xmlDoc.loadXML(document.body.outerHTML)

这只有在您的 HTML 文档被格式化为 XHTML 标准时才真正起作用。此外,BODY 标记将是根节点,因此您必须将 XPATH 更改为“/BODY/DIV[9]/DIV[2]”

于 2008-10-08T07:41:58.190 回答