adnan kamili
adnan kamili

Reputation: 9455

Compare two DOM elements using xpath

We can have multiple xpaths for the same DOM element, Firepath generates xpaths using id's and classes. Here are two xpaths for the same element:

.//*[@id='1']/div/ul/li[5]

.tab-header-home

Now I wish to generate unique class based xpaths from id based xpaths. The class xpaths generated by Firepath may point to more than one element, not unique. But the id xpaths generated by firepath are always unique, i.e. point to single element.

So, I am generating a mapping between two wherever possible. But I need to test the following:

 xpath( .//*[@id='1']/div/ul/li[5]) == xpath(.tab-header-home )

to make sure that the class xpath i created corresponds to the required DOM element. Any help will be highly appreciated. An example of xpath which i wish to generate is:

.//*[@id='29']/descendant::div[@class='template-parent-search-box']

The target is to decrease the depth of xpaths so that any change in the DOM structure like adding an Div etc. should not render the xpath invalid.

Upvotes: 1

Views: 538

Answers (1)

Brett Zamir
Brett Zamir

Reputation: 14345

How exactly are you using XPath? Be aware that XPath may not work in IE, at least without a shim (its native support is only for XML).

But with a proper polyfill/shim, you should be able to just compare the DOM element (or iterate through each XPath result if multiple are returned and compare each individual item).

if (xPathClassDOM === xPathIDDDOM) {...}

Also, .tab-header-home is not XPath, but a CSS Selector, but you can still compare it with an XPath-retrieved element if you have grabbed the DOM element, e.g., via document.querySelector).

For example:

JavaScript:

var classBasedExpression = ".tab-header-home"; // CSS-Selector-based
var idBasedExpression = ".//*[@id='1']/div/ul/li[5]"; // XPath-based


var firstCSSSelection = document.querySelector(classBasedExpression);

var iterator = document.evaluate(idBasedExpression, document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null ); 

try {
  var thisNode = iterator.iterateNext();

  while (thisNode) {
    if (firstCSSSelection === thisNode) {
      alert('found!')
      break;
    }
    thisNode = iterator.iterateNext();
  }
}
catch (e) {
    alert('error:' + e);
}

HTML:

<div id="1">
    <div>
        <ul>
            <li>a</li>
            <li>b</li>
            <li>c</li>
            <li>d</li>
            <li class="tab-header-home">e</li>
        </ul>
    </div>
</div>

JSFiddle

Upvotes: 1

Related Questions