Javascript获取节点的XPath

Javascript获取节点的XPath,javascript,dom,xpath,Javascript,Dom,Xpath,Javascript中是否有返回DOM元素XPath字符串的方法?节点没有唯一的XPath,因此您必须确定构建路径的最合适方法。在可用的地方使用ID?文档中的数字位置?相对于其他元素的位置 请参阅中的getPathTo(),了解一种可能的方法。我从另一个示例重构了它。它将尝试检查是否存在唯一id,如果是,则使用该大小写来缩短表达式 函数createXPathFromElement(elm){ var allNodes=document.getElementsByTagName('*'); for

Javascript中是否有返回DOM元素XPath字符串的方法?

节点没有唯一的XPath,因此您必须确定构建路径的最合适方法。在可用的地方使用ID?文档中的数字位置?相对于其他元素的位置


请参阅中的
getPathTo()
,了解一种可能的方法。

我从另一个示例重构了它。它将尝试检查是否存在唯一id,如果是,则使用该大小写来缩短表达式

函数createXPathFromElement(elm){
var allNodes=document.getElementsByTagName('*');
for(var segs=[];elm&&elm.nodeType==1;elm=elm.parentNode)
{ 
if(elm.hasAttribute('id')){
var uniqueIdCount=0;
对于(var n=0;n1)中断;
}; 
如果(uniqueIdCount==1){
segs.unshift('id('+elm.getAttribute('id')+'));
返回segs.join('/');
}否则{
segs.unshift(elm.localName.toLowerCase()+”[@id=“”+elm.getAttribute('id')+“]);
} 
}else if(elm.hasAttribute('class')){
segs.unshift(elm.localName.toLowerCase()+”[@class=“”+elm.getAttribute('class')+“]);
}否则{
对于(i=1,sib=elm.previousSibling;sib;sib=sib.previousSibling){
if(sib.localName==elm.localName)i++;};
segs.unshift(elm.localName.toLowerCase()++'['+i+']');
}; 
}; 
返回segs.length?'/'+segs.join('/'):null;
}; 
函数lookupElementByXPath(路径){
var evaluator=新的XPathEvaluator();
var result=evaluator.evaluate(路径,document.documentElement,null,XPathResult.FIRST\u ORDERED\u NODE\u TYPE,null);
返回result.singleNodeValue;
} 

MDN上的函数给出了类似的解决方案:

函数getXPathForElement(el,xml){ var xpath=''; var pos,临时项目2; 而(el!==xml.documentElement){ pos=0; tempitem2=el; while(临时项目2){ if(tempitem2.nodeType==1&&tempitem2.nodeName==el.nodeName){//如果它是同名的元素\节点 pos+=1; } tempitem2=tempitem2.previousSibling; } xpath=“*[name()='”+el.nodeName+“'和namespace-uri()='”+(el.namespaceURI==null?“”:el.namespaceURI)+“][”+pos+']'+'/'+xpath; el=el.parentNode; } xpath='/*'+“[name()=”+xml.documentElement.nodeName+”,namespace-uri()='+(el.namespaceURI===null?'':el.namespaceURI)+“]+'+'/'+xpath; xpath=xpath.replace(/\/$/,“”); 返回xpath; } 也可能值得一试。

以下是一个函数式编程风格的ES6函数:

函数getXPathForElement(元素){ 常量idx=(sib,名称)=>sib ?idx(sib.previousElementSibling,name | | sib.localName)+(sib.localName==name) : 1; 常量segs=elm=>!elm | | elm.nodeType!==1 ? [''] :elm.id&&document.getElementById(elm.id)==elm ?[`id(${elm.id})`] :[…segs(elm.parentNode),`${elm.localName.toLowerCase()}[${idx(elm)}]`]; 返回segs(元素).join('/'); } 函数getElementByXPath(路径){ 返回(新的XPathEvaluator()) .evaluate(路径,document.documentElement,null, XPathResult.FIRST_ORDERED_NODE_TYPE,null) .singleNodeValue; } //演示: const li=document.querySelector('li:n个子(2)'); const path=getXPathForElement(li); console.log(路径); log(li==getElementByXPath(path));//正确

  • 选项
标题
  • abc
  • 选择这个
函数getElementXPath(元素){ 如果(!element)返回null if(element.id){ 返回`/*[@id=${element.id}]` }else if(element.tagName==='BODY'){ 返回“/html/body” }否则{ const sameTagSiblings=Array.from(element.parentNode.childNodes) .filter(e=>e.nodeName===element.nodeName) const idx=sameTagSiblings.indexOf(元素) 返回getElementXPath(element.parentNode)+ '/' + element.tagName.toLowerCase()+ (sameTagSiblings.length>1?`[${idx+1}]``:“”) } } log(getElementXPath(document.querySelector('a div')))

def

只需在函数
getXPathOfElement
中传递元素,就可以得到
Xpath

function getXPathOfElement(elt)
{
     var path = "";
     for (; elt && elt.nodeType == 1; elt = elt.parentNode)
     {
    idx = getElementIdx(elt);
    xname = elt.tagName;
    if (idx > 1) xname += "[" + idx + "]";
    path = "/" + xname + path;
     }

     return path;   
}
function getElementIdx(elt)
{
    var count = 1;
    for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling)
    {
        if(sib.nodeType == 1 && sib.tagName == elt.tagName) count++
    }

    return count;
}
我已经修改了,以便从下面的devtools计算XPath

要以书面形式使用它,您需要调用
Elements.DOMPath.xPath(,false)
。最后一个参数控制是获取较短的“复制XPath”(if
true
)还是“复制完整XPath”

//作者版权所有。版权所有。
//此源代码的使用受BSD样式许可证的约束,该许可证可以
//在许可证文件中找到。
元素={};
Elements.DOMPath={};
/**
*@param{!Node}Node
*@param{boolean=}已优化
*@return{string}
*/
Elements.DOMPath.xPath=函数(节点,优化){
if(node.nodeType==node.DOCUMENT\u节点){
返回“/”;
}
常数步长=[];
让contextNode=node;
while(contextNode){
const step=Elements.DOMPath.\u xPathValue(contextNode,优化);
如果(!步){
打破
}//错误-提前退出。
步骤。推(步骤);
如果(步骤优化){
打破
}
contextNode=contextNode.parentNode;
}
步骤。反向();
返回(steps.length&&steps[0]。优化?“”:“/”)+steps.join(“/”);