Languages
[Edit]
EN

JavaScript - web browser built-in XPath API example

9 points
Created by:
Kate_C
2952

In this short article we would like to show how to use built-in XPath API in Web Browser JavaScript.

Simple example:

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<body>
  <div id="element">Empty</div>
  <script>
    
    var result = document.evaluate("//*[@id='element']", document.body);
    var element = result.iterateNext();
    
    if (element) {
    	console.log(element.outerHTML);
    }
    
  </script>
</body>
</html>

Note: above example shows how to get element by id with XPath.

XPath 1.0 appeard in 1990. Since begining 3 additional versions of XPath appeard: 2.0 in 2007, 3.0 in 2014 and 3.1 in 2017. The web browsers that provide XPath API are: Chrome, Firefox, Edge, Opera, Internet Explorer, and Safari.

As once of web browsers, Internet Explorer provides different API for XPath usage - at this time IE is not supported and it is not recommended to support that browser in web projects (we have 2020). So we will not focus on, how to use XPath in IE.

Practical example:

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<body>
  <div id="element">
    <span class="text">Empty</span>
    <span class="text">Some text ...</span>
    <span class="info">Empty</span>
    <span class="info">Some text ...</span>
  </div>
  <script>
    
    var element = document.querySelector('#element');
    var result = document.evaluate("//span[@class='text']", element);

    var element = null;
    while (element = result.iterateNext()) {
        console.log(element.outerHTML);
    }    
    
  </script>
</body>
</html>

More complicated example

 The example shows how to get elements by class name and containing text using XPath.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<body>
  <div id="element">
    <span class="text">Empty</span>
    <span class="text">Some text ...</span>
    <span class="info">Empty</span>
    <span class="info">Some text ...</span>
  </div>
  <script>
    
    var element = document.querySelector('#element');

    var result1 = document.evaluate("//span", element);
    var result2 = document.evaluate("//span[@class='text']", element);
    var result3 = document.evaluate("//span[@class='info']", element);
    var result4 = document.evaluate("//span[text()='Some text ...']", element);

    function printElements(result) {
    	var element = null;
        while (element = result.iterateNext()) {
            console.log('  ' + element.outerHTML);
        }
    }
    
    console.log('\n//span -------------------------------------');
    printElements(result1);

    console.log('\n//span[@class=\'text\'] --------------------');
    printElements(result2);

    console.log('\n//span[@class=\'info\'] --------------------');
    printElements(result3);

    console.log('\n//span[text()=\'Some text ...\'] -----------');
    printElements(result4);
    
  </script>
</body>
</html>

Note: when we use AJAX, document can be replaced with xhr.responseXML object.

Universal example

Sometimes it is necessary to to find XML Document before XPath querring. That situation appears when we have node that can be located in different document. The solution is to use documentElement property that can be used to create XPath evaluator.

Check below example to see how it works:

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<body>
  <div id="element">
    <span class="text">Empty</span>
    <span class="text">Some text ...</span>
    <span class="info">Empty</span>
    <span class="info">Some text ...</span>
  </div>
  <script>

	function findDocument(node) {
		var tmp = node.ownerDocument || node;
		return tmp.documentElement;
	}

	function NodeEvaluator(node) {
		var document = findDocument(node);
		var evaluator = new XPathEvaluator();
		var resolver = evaluator.createNSResolver(document);
		
		this.evaluate = function(expression) {
			return evaluator.evaluate(expression, node, resolver, XPathResult.ANY_TYPE, null);
		};
	}

    var element = document.querySelector('#element');
	var evaluator = new NodeEvaluator(element);

    var result1 = evaluator.evaluate("//span");
    var result2 = evaluator.evaluate("//span[@class='text']");
    var result3 = evaluator.evaluate("//span[@class='info']");
    var result4 = evaluator.evaluate("//span[text()='Some text ...']");

    function printElements(result) {
    	var element = null;
        while (element = result.iterateNext()) {
            console.log('  ' + element.outerHTML);
        }
    }

    console.log('\n//span -------------------------------------');
    printElements(result1);

    console.log('\n//span[@class=\'text\'] --------------------');
    printElements(result2);

    console.log('\n//span[@class=\'info\'] --------------------');
    printElements(result3);

    console.log('\n//span[text()=\'Some text ...\'] -----------');
    printElements(result4);

  </script>
</body>
</html>
Hey ūüĎč
Would you like to know what we do?
  • Dirask is online IT community for professionals and hobbyist to share their knowledge and help each other in extraordinary easy way.
  • We welcome everyone
    no matter what the experience,
    no matter how basic the question is,
    this community will help you.