如何使用Javascript来计算元素的XPath位置? [英] How to calculate the XPath position of an element using Javascript?

查看:134
本文介绍了如何使用Javascript来计算元素的XPath位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个包含不同类型标签的大型HTML文件,类似于您现在看到的StackOverflow。



现在让我们假设您点击页面上的一个元素,Javascript函数看起来像什么,它会计算引用该特定元素的最基本的XPath?



我知道有一种无限的引用方式到XPath中的那个元素,但是我正在寻找一些只查看DOM树的东西,而不考虑ID,类等。

示例:

p>

 < html> 
< head>< title>水果< / title>< / head>
< body>
< ol>
< li>香蕉< / li>
< li>苹果< / li>
< li>草莓< / li>
< / ol>
< / body>
< / html>

假设您点击苹果。 Javascript函数将返回以下内容:

$ p $ / html / body / ol / li [2]

它基本上只是一直向上到达HTML元素的DOM树。



为了澄清,'点击'事件处理程序不是问题。我可以做这项工作。我只是不确定如何计算元素在DOM树中的位置并将其表示为XPath。


任何有或没有使用的答案我很欣赏JQuery库。



PPS
我对XPath完全陌生,所以我甚至可能在上面的例子中犯了一个错误,但是您会获得这个想法。



编辑于2010年8月11日:看起来像别人问了一个类似的问题:为选定的文本节点生成/获取Xpath

解决方案

Firebug可以做到这一点,它是开源的( BSD ),所以你可以重用他们的实施,不需要任何库。



第三方编辑



这是上面链接源文件的摘录。以防万一上面的链接会改变。

  Xpath.getElementXPath = function(element)$ b请检查源代码是否受益于更改和更新或提供的完整功能集。 $ b {
if(element& element.id)
return'// * [@ id =''+ element.id +']';
else
return Xpath.getElementTreeXPath(element);
};

以上代码调用此函数。
Attention我添加了一些换行来避免水平滚动条

pre $ Xpath.getElementTreeXPath = function(element)
{
var paths = []; //使用nodeName(而不是localName)
//包含名称空间前缀(如果有的话)。 (;元素&< element.nodeType == Node.ELEMENT_NODE;
element = element.parentNode)

{
var index = 0;
var hasFollowingSiblings = false;
for(var sibling = element.previousSibling; sibling;
sibling = sibling.previousSibling)
{
//忽略文档类型声明。
if(sibling.nodeType == Node.DOCUMENT_TYPE_NODE)
continue;

if(sibling.nodeName == element.nodeName)
++ index;
}

for(var sibling = element.nextSibling;
sibling&&!hasFollowingSiblings;
sibling = sibling.nextSibling)
{
if(sibling.nodeName == element.nodeName)
hasFollowingSiblings = true;


var tagName =(element.prefix?element.prefix +::)
+ element.localName;
var pathIndex =(index || hasFollowingSiblings?[
+(index + 1)+]:);
paths.splice(0,0,tagName + pathIndex);
}

return paths.length? /+ paths.join(/):null;
};


Let's say I have a large HTML file with different kinds of tags, similar to the StackOverflow one you're looking at right now.

Now let's say you click an element on the page, what would the Javascript function look like that calculates the most basic XPath that refers to that specific element?

I know there are an infinite ways of refering to that element in XPath, but I'm looking for something that just looks at the DOM tree, with no regard for IDs, classes, etc.

Example:

<html>
<head><title>Fruit</title></head>
<body>
<ol>
  <li>Bananas</li>
  <li>Apples</li>
  <li>Strawberries</li>
</ol>
</body>
</html>

Let's say you click on Apples. The Javascript function would return the following:

/html/body/ol/li[2]

It would basically just work its way upward the DOM tree all the way to the HTML element.

Just to clarify, the 'on-click' event-handler isn't the problem. I can make that work. I'm just not sure how to calculate the element's position within the DOM tree and represent it as an XPath.

PS Any answer with or without the use of the JQuery library is appreciated.

PPS I completely new to XPath, so I might even have made a mistake in the above example, but you'll get the idea.

Edit at August 11, 2010: Looks like somebody else asked a similar question: generate/get the Xpath for a selected textnode

解决方案

Firebug can do this, and it's open source (BSD) so you can reuse their implementation, which does not require any libraries.

3rd party edit

This is an extract from the linked source above. Just in case the link above will change. Please check the source to benefit from changes and updates or the full featureset provided.

Xpath.getElementXPath = function(element)
{
    if (element && element.id)
        return '//*[@id="' + element.id + '"]';
    else
        return Xpath.getElementTreeXPath(element);
};

Above code calls this function. Attention i added some line-wrapping to avoid horizontal scroll bar

Xpath.getElementTreeXPath = function(element)
{
    var paths = [];  // Use nodeName (instead of localName) 
    // so namespace prefix is included (if any).
    for (; element && element.nodeType == Node.ELEMENT_NODE; 
           element = element.parentNode)
    {
        var index = 0;
        var hasFollowingSiblings = false;
        for (var sibling = element.previousSibling; sibling; 
              sibling = sibling.previousSibling)
        {
            // Ignore document type declaration.
            if (sibling.nodeType == Node.DOCUMENT_TYPE_NODE)
                continue;

            if (sibling.nodeName == element.nodeName)
                ++index;
        }

        for (var sibling = element.nextSibling; 
            sibling && !hasFollowingSiblings;
            sibling = sibling.nextSibling)
        {
            if (sibling.nodeName == element.nodeName)
                hasFollowingSiblings = true;
        }

        var tagName = (element.prefix ? element.prefix + ":" : "") 
                          + element.localName;
        var pathIndex = (index || hasFollowingSiblings ? "[" 
                   + (index + 1) + "]" : "");
        paths.splice(0, 0, tagName + pathIndex);
    }

    return paths.length ? "/" + paths.join("/") : null;
};

这篇关于如何使用Javascript来计算元素的XPath位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆