-
Notifications
You must be signed in to change notification settings - Fork 41
/
get_xpath.js
70 lines (67 loc) · 1.98 KB
/
get_xpath.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// Taken with some modifications from - https://stackoverflow.com/questions/47069382/want-to-retrieve-xpath-of-given-webelement
function absoluteXPath(element) {
let comp, comps = [];
let parent = null;
let xpath = '';
let getPos = function(element) {
let position = 0, curNode, prevNode, nextNode;
if (element.nodeType == Node.ATTRIBUTE_NODE) {
return null;
}
prevNode = element.previousSibling;
nextNode = element.nextSibling;
while (prevNode) {
if (prevNode.nodeName == element.nodeName) {
position = 1;
break;
}
prevNode = prevNode.previousSibling;
}
while (nextNode) {
if (nextNode.nodeName == element.nodeName) {
position = 1;
break;
}
nextNode = nextNode.nextSibling;
}
for (curNode = element.previousSibling; curNode; curNode = curNode.previousSibling) {
if (curNode.nodeName == element.nodeName) {
++position;
}
}
return position;
};
if (element instanceof Document) {
return '/';
}
for (; element && !(element instanceof Document); element = element.nodeType == Node.ATTRIBUTE_NODE ? element.ownerElement : element.parentNode) {
comp = comps[comps.length] = {};
switch (element.nodeType) {
case Node.TEXT_NODE:
comp.name = 'text()';
break;
case Node.ATTRIBUTE_NODE:
comp.name = '@' + element.nodeName;
break;
case Node.PROCESSING_INSTRUCTION_NODE:
comp.name = 'processing-instruction()';
break;
case Node.COMMENT_NODE:
comp.name = 'comment()';
break;
case Node.ELEMENT_NODE:
comp.name = element.nodeName;
break;
}
comp.position = getPos(element);
}
for (let i = comps.length - 1; i >= 0; i--) {
comp = comps[i];
xpath += '/' + comp.name.toLowerCase();
if (comp.position !== null && comp.position != '0') {
xpath += '[' + comp.position + ']';
}
}
return xpath;
}
return absoluteXPath(arguments[0]);