How to calculate the XPath position of an element using Javascript?
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 get XPath of a node
There's not a unique XPath to a node, so you'll have to decide what's the most appropriate way of constructing a path. Use IDs where available? Numeral position in the document? Position relative to other elements?
See getPathTo()
in this answer for one possible approach.
How do i get the xpath of an element in an X/HTML file
You can extract this functionality from an XPath tool I once wrote:
http://webkitchen.cz/lab/opera/xpath-tool/xpath-tool.js
Edit: here you go:
function getXPath(node) {
var comp, comps = [];
var parent = null;
var xpath = '';
var getPos = function(node) {
var position = 1, curNode;
if (node.nodeType == Node.ATTRIBUTE_NODE) {
return null;
}
for (curNode = node.previousSibling; curNode; curNode = curNode.previousSibling) {
if (curNode.nodeName == node.nodeName) {
++position;
}
}
return position;
}
if (node instanceof Document) {
return '/';
}
for (; node && !(node instanceof Document); node = node.nodeType == Node.ATTRIBUTE_NODE ? node.ownerElement : node.parentNode) {
comp = comps[comps.length] = {};
switch (node.nodeType) {
case Node.TEXT_NODE:
comp.name = 'text()';
break;
case Node.ATTRIBUTE_NODE:
comp.name = '@' + node.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 = node.nodeName;
break;
}
comp.position = getPos(node);
}
for (var i = comps.length - 1; i >= 0; i--) {
comp = comps[i];
xpath += '/' + comp.name;
if (comp.position != null) {
xpath += '[' + comp.position + ']';
}
}
return xpath;
}
It might need some changes if you want it to work in IE as well.
Find specific element position in XPath after checking a condition
This is one possible way : (formatted for readability)
//table[@class='detailTable']
//tr
/td[*[contains(.,'Statement Date')]]
/following-sibling::td[1]
/*[position()
=
count(
parent::td
/preceding-sibling::td[1]
/*[contains(.,'Statement Date')]/preceding-sibling::*
)+1
]
explanation :
..../td[*[contains(.,'Statement Date')]]
: From the beginning up to this part, the XPath will findtd
element where, at least, one of its children contains text"Statement Date"
/following-sibling::td[1]
: from previously matchedtd
, navigate to the nearest following siblingtd
.../*[position() = count(parent::td/preceding-sibling::td[1]/*[contains(.,'Statement Date')]/preceding-sibling::*)+1]
: ...and return child element at position equals to position of element that contains text"Statement Date"
in the previoustd
. Notice that we usecount(preceding-sibling::*)+1
to get position index of the element containing text"Statement Date"
here.
Get element's xpath in javascript
There are many ways howto access an element with XPath. For example you can access it by node name or by the value of one of it's attributes or child nodes. So you can not expect that javascript gives you exactly one of them.
But as you have the id, the simplest xpath query to access the element would be:
//*[@id="THE_ID"]
How to create a Xpath of the clicked element using Javascript or Jquery?
You need to loop through clicked element and it parents to do this work. So you can call a function nesting to do this work.
var xpath;$("*").click(function(e){ xpath = ''; addXpath($(this)); console.log(xpath); e.stopPropagation();});
function addXpath($ele){ var tagName = $ele[0].tagName.toLowerCase(); var index = $ele.parent().children(tagName).index($ele)+1; xpath = '/'+tagName +'['+index+']'+ xpath; !$ele.parent().is(document) ? addXpath($ele.parent()) : "";}
body {background: green}.header {background: orange}.row_in {background: yellow}.row_in_in {background: blue}span {background: red}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><div class="header">Countries</div><div class="row"><div class="row_in"> <div class="row_in_in"> <span>India</span> </div></div></div><div class="row"><div class="row_in"> <div class="row_in_in"> <span>USA</span> </div></div></div><div class="row"><div class="row_in"> <div class="row_in_in"> <span>UK</span> </div></div></div><div class="row"><div class="row_in"> <div class="row_in_in"> <span>France</span> </div></div></div>
How to use xpath in JavaScript?
It would do what you want:
function xpathFindById(id) {
return document.evaluate(".//*[@id='" + id + "']", document.lastChild, null,
XPathResult.ANY_TYPE, null).iterateNext();
}
var content = xpathFindById("content");
Finding an element in another element by Xpath
You missed .
at the heading of following xpath, .
at here means search element start from current node which is the parent node. Without .
at here your xpath tells browser to search element start from the beginning of the HTML.
card.element(by.xpath('.//ep-check-box[.//span[text()="'+label+'"]]'));
Related Topics
Jquery/JavaScript Collision Detection
Best Way to Track Onchange As-You-Type in Input Type="Text"
How to Run a Function When the Page Is Loaded
Contenteditable, Set Caret At the End of the Text (Cross-Browser)
Html Form Readonly Select Tag/Input
Disabling Browser Print Options (Headers, Footers, Margins) from Page
Jquery Disable/Enable Submit Button
How to Implement "Select All" Check Box in Html
Browser Detection Versus Feature Detection
How to Correctly Iterate Through Getelementsbyclassname
Link Index.Html Client.Js and Server.Js
How Can JavaScript Upload a Blob
How Can Get the Text of a Div Tag Using Only JavaScript (No Jquery)
How to Let a Table'S Body Scroll But Keep Its Head Fixed in Place
Prevent Page Load on Jquery Form Submit With None Display Button
How to Pass Parameters on Onchange of HTML Select
How to Change an Element'S Class With JavaScript
How to Show Page Loading Div Until the Page Has Finished Loading