Search code examples
javascriptarraysgoogle-chromexpathiterator

JavaScript: How to access the n-th result from an xpath search?


Problem Description

I am trying to use xpath to locate the "Messi" node from the HTML below. To minimize coding efforts, I am hoping for a solution that uses an array index, instead of looping through an iterator.

My assumption is that the most standard and simplest API is XPathExpression.evaluate(). If there are better APIs, please kindly share.

By the way, I need to make changes to the DOM Node from the returned result. So, XPathResult.resultType will be set to ORDERED_NODE_ITERATOR_TYPE, and therefore XPathResult.snapshotItem() cannot be used.

HTML Example

<html>
<body>

<div>
    <div>NumberOne</div>
    <div>NumberTwo_Mbappe</div>
    <div>NumberOne</div>
    <div>NumberTwo_Ronaldo</div>
    <div>NumberTwo_Messi</div>
</div>

</body>
</html>

Code to get the XPath Results

Running the code below will return an iterator from the above html.

let xpathIterator = new XPathEvaluator()
                        .createExpression("//*[starts-with(text(), 'NumberTwo')]")
                        .evaluate(
                            document, 
                            XPathResult.ORDERED_NODE_ITERATOR_TYPE
                        );

Existing iterator solution for extracting the n-th item

The existing XPathResult interface only has an iterateNext() method, so it will take six lines of code to extract the n-th item:

let n = 3;
while (n > 0) { 
    xpathIterator.iterateNext(); 
    n--; 
}
xpathIterator.iterateNext();

Ideal array solution for extracting the n-th item

Since XPath and Chrome are used by millions of people everyday, ideally, there should be a way to obtain the n-th item directly using an array index (as the following code shows). I would be surprised if such an API doesn't already exist.

let v = xpathResult[2];

The ideal solution doesn't necessarily need to use XPathExpression.evaluate(). I am open to any solutions that use standard JavaScript functions supported by Chrome.

(Hopefully, we don't need to use a function. If a function must be used, it would be good to have no more than 2 to 3 lines of ESLint-linted codes.)

Thanks!

Related Posts

Since XPathResult.resultType is not an iterable, the following posts don't apply:


Solution

  • This will get the third item in your example:

    let v = [...new Array(3)].map( () => xpathIterator.iterateNext() ); 
    v[2];