Recent from talks
Contribute something
Nothing was collected or created yet.
XPath
View on WikipediaThis article needs additional citations for verification. (August 2010) |
| XPath | |
|---|---|
| Paradigm | Query language |
| Developer | W3C |
| First appeared | 1998 |
| Stable release | 3.1
/ March 21, 2017 |
| Influenced by | |
| XSLT, XPointer | |
| Influenced | |
| XML Schema, XForms, JSONPath | |
XPath (XML Path Language) is an expression language designed to support the query or transformation of XML documents. It was defined by the World Wide Web Consortium (W3C) in 1999,[1] and can be used to compute values (e.g., strings, numbers, or Boolean values) from the content of an XML document. Support for XPath exists in applications that support XML, such as web browsers, and many programming languages.
The XPath language is based on a tree representation of the XML document, and provides the ability to navigate around the tree, selecting nodes by a variety of criteria.[2][3] In popular use (though not in the official specification), an XPath expression is often referred to simply as "an XPath".
Originally motivated by a desire to provide a common syntax and behavior model between XPointer and XSLT, subsets of the XPath query language are used in other W3C specifications such as XML Schema, XForms and the Internationalization Tag Set (ITS).
XPath has been adopted by a number of XML processing libraries and tools, many of which also offer CSS Selectors, another W3C standard, as a simpler alternative to XPath.
Versions
[edit]There are several versions of XPath in use. XPath 1.0 was published in 1999, XPath 2.0 in 2007 (with a second edition in 2010), XPath 3.0 in 2014, and XPath 3.1 in 2017. However, XPath 1.0 is still the version that is most widely available.[1]
- XPath 1.0 became a Recommendation on 16 November 1999 and is widely implemented and used, either on its own (called via an API from languages such as Java, C#, Python or JavaScript), or embedded in languages such as XSLT, XProc, XML Schema or XForms.
- XPath 2.0 became a Recommendation on 23 January 2007, with a second edition published on 14 December 2010. A number of implementations exist but are not as widely used as XPath 1.0. The XPath 2.0 language specification is much larger than XPath 1.0 and changes some of the fundamental concepts of the language such as the type system.
- The most notable change is that XPath 2.0 is built around the XQuery and XPath Data Model (XDM) that has a much richer type system.[a] Every value is now a sequence (a single atomic value or node is regarded as a sequence of length one). XPath 1.0 node-sets are replaced by node sequences, which may be in any order.
- To support richer type sets, XPath 2.0 offers a greatly expanded set of functions and operators.
- XPath 2.0 is in fact a subset of XQuery 1.0. They share the same data model (XDM). It offers a
forexpression that is a cut-down version of the "FLWOR" expressions in XQuery. It is possible to describe the language by listing the parts of XQuery that it leaves out: the main examples are the query prolog, element and attribute constructors, the remainder of the "FLWOR" syntax, and thetypeswitchexpression.
- XPath 3.0 became a Recommendation on 8 April 2014.[4] The most significant new feature is support for functions as first-class values.[5] XPath 3.0 is a subset of XQuery 3.0, and most current implementations (April 2014) exist as part of an XQuery 3.0 engine.
- XPath 3.1 became a Recommendation on 21 March 2017.[6] This version adds new data types: maps and arrays, largely to underpin support for JSON.

Syntax and semantics (XPath 1.0)
[edit]The most important kind of expression in XPath is a location path. A location path consists of a sequence of location steps. Each location step has three components:
- an axis
- a node test
- zero or more predicates.
An XPath expression is evaluated with respect to a context node. An Axis Specifier such as 'child' or 'descendant' specifies the direction to navigate from the context node. The node test and the predicate are used to filter the nodes specified by the axis specifier: For example, the node test 'A' requires that all nodes navigated to must have label 'A'. A predicate can be used to specify that the selected nodes have certain properties, which are specified by XPath expressions themselves.
The XPath syntax comes in two flavors: the abbreviated syntax, is more compact and allows XPaths to be written and read easily using intuitive and, in many cases, familiar characters and constructs. The full syntax is more verbose, but allows for more options to be specified, and is more descriptive if read carefully.
Abbreviated syntax
[edit]The compact notation allows many defaults and abbreviations for common cases. Given source XML containing at least
<A>
<B>
<C/>
</B>
</A>
the simplest XPath takes a form such as
/A/B/C
that selects C elements that are children of B elements that are children of the A element that forms the outermost element of the XML document. The XPath syntax is designed to mimic URI (Uniform Resource Identifier) and Unix-style file path syntax.
More complex expressions can be constructed by specifying an axis other than the default 'child' axis, a node test other than a simple name, or predicates, which can be written in square brackets after any step. For example, the expression
A//B/*[1]
selects the first child ('*[1]'), whatever its name, of every B element that itself is a child or other, deeper descendant ('//') of an A element that is a child of the current context node (the expression does not begin with a '/'). The predicate [1] binds more tightly than the / operator. To select the first node selected by the expression A//B/*, write (A//B/*)[1]. Note also, index values in XPath predicates (technically, 'proximity positions' of XPath node sets) start from 1, not 0 as common in languages like C and Java.
Expanded syntax
[edit]In the full, unabbreviated syntax, the two examples above would be written
/child::A/child::B/child::Cchild::A/descendant-or-self::node()/child::B/child::node()[position()=1]
Here, in each step of the XPath, the axis (e.g. child or descendant-or-self) is explicitly specified, followed by :: and then the node test, such as A or node() in the examples above.
Here the same, but shorter: A//B/*[position()=1]
Axis specifiers
[edit]Axis specifiers indicate navigation direction within the tree representation of the XML document. The axes available are:[b]
| Full syntax | Abbreviated syntax | Notes |
|---|---|---|
ancestor |
||
ancestor-or-self |
||
attribute
|
@
|
@abc is short for attribute::abc
|
child |
xyz is short for child::xyz
| |
descendant |
||
descendant-or-self
|
//
|
// is short for /descendant-or-self::node()/
|
following |
||
following-sibling |
||
namespace |
||
parent
|
..
|
.. is short for parent::node()
|
preceding |
||
preceding-sibling |
||
self
|
.
|
. is short for self::node()
|
As an example of using the attribute axis in abbreviated syntax, //a/@href selects the attribute called href in a elements anywhere in the document tree.
The expression . (an abbreviation for self::node()) is most commonly used within a predicate to refer to the currently selected node.
For example, h3[.='See also'] selects an element called h3 in the current context, whose text content is See also.
Node tests
[edit]Node tests may consist of specific node names or more general expressions. In the case of an XML document in which the namespace prefix gs has been defined, //gs:enquiry will find all the enquiry elements in that namespace, and //gs:* will find all elements, regardless of local name, in that namespace.
Other node test formats are:
- comment()
- finds an XML comment node, e.g.
<!-- Comment --> - text()
- finds a node of type text excluding any children, e.g. the
helloin<k>hello<m> world</m></k> - processing-instruction()
- finds XML processing instructions such as
<?php echo $a; ?>. In this case,processing-instruction('php')would match. - node()
- finds any node at all.
Predicates
[edit]Predicates, written as expressions in square brackets, can be used to filter a node-set according to some condition. For example, a returns a node-set (all the a elements which are children of the context node), and a[@href='help.php'] keeps only those elements having an href attribute with the value help.php.
There is no limit to the number of predicates in a step, and they need not be confined to the last step in an XPath. They can also be nested to any depth. Paths specified in predicates begin at the context of the current step (i.e. that of the immediately preceding node test) and do not alter that context. All predicates must be satisfied for a match to occur.
When the value of the predicate is numeric, it is syntactic-sugar for comparing against the node's position in the node-set (as given by the function position()). So p[1] is shorthand for p[position()=1] and selects the first p element child, while p[last()] is shorthand for p[position()=last()] and selects the last p child of the context node.
In other cases, the value of the predicate is automatically converted to a Boolean. When the predicate evaluates to a node-set, the result is true when the node-set is non-empty[clarify]. Thus p[@x] selects those p elements that have an attribute named x.
A more complex example: the expression a[/html/@lang='en'][@href='help.php'][1]/@target selects the value of the target attribute of the first a element among the children of the context node that has its href attribute set to help.php, provided the document's html top-level element also has a lang attribute set to en. The reference to an attribute of the top-level element in the first predicate affects neither the context of other predicates nor that of the location step itself.
Predicate order is significant if predicates test the position of a node. Each predicate takes a node-set returns a (potentially) smaller node-set. So a[1][@href='help.php'] will find a match only if the first a child of the context node satisfies the condition @href='help.php', while a[@href='help.php'][1] will find the first a child that satisfies this condition.
Functions and operators
[edit]XPath 1.0 defines four data types: node-sets (sets of nodes with no intrinsic order), strings, numbers and Booleans.
The available operators are:
- The
/,//and[...]operators, used in path expressions, as described above. - A union operator,
|, which forms the union of two node-sets. - Boolean operators
andandor, and a functionnot() - Arithmetic operators
+,-,*,div(divide), andmod - Comparison operators
=,!=,<,>,<=,>=
The function library includes:
- Functions to manipulate strings: concat(), substring(), contains(), substring-before(), substring-after(), translate(), normalize-space(), string-length()
- Functions to manipulate numbers: sum(), round(), floor(), ceiling()
- Functions to get properties of nodes: name(), local-name(), namespace-uri()
- Functions to get information about the processing context: position(), last()
- Type conversion functions: string(), number(), boolean()
Some of the more commonly useful functions are detailed below.[c]
Node set functions
[edit]- position()
- returns a number representing the position of this node in the sequence of nodes currently being processed (for example, the nodes selected by an xsl:for-each instruction in XSLT).
- count(node-set)
- returns the number of nodes in the node-set supplied as its argument.
String functions
[edit]- string(object?)
- converts any of the four XPath data types into a string according to built-in rules. If the value of the argument is a node-set, the function returns the string-value of the first node in document order, ignoring any further nodes.
- concat(string, string, string*)
- concatenates two or more strings
- starts-with(s1, s2)
- returns
trueifs1starts withs2 - contains(s1, s2)
- returns
trueifs1containss2 - substring(string, start, length?)
- example:
substring("ABCDEF",2,3)returnsBCD. - substring-before(s1, s2)
- example:
substring-before("1999/04/01","/")returns1999 - substring-after(s1, s2)
- example:
substring-after("1999/04/01","/")returns04/01 - string-length(string?)
- returns number of characters in string
- normalize-space(string?)
- all leading and trailing whitespace is removed and any sequences of whitespace characters are replaced by a single space. This is very useful when the original XML may have been prettyprint formatted, which could make further string processing unreliable.
Boolean functions
[edit]- not(boolean)
- negates any Boolean expression.
- true()
- evaluates to true.
- false()
- evaluates to false.
Number functions
[edit]- sum(node-set)
- converts the string values of all the nodes found by the XPath argument into numbers, according to the built-in casting rules, then returns the sum of these numbers.
Usage examples
[edit]Expressions can be created inside predicates using the operators: =, !=, <=, <, >= and >. Boolean expressions may be combined with brackets () and the Boolean operators and and or as well as the not() function described above. Numeric calculations can use *, +, -, div and mod. Strings can consist of any Unicode characters.
//item[@price > 2*@discount] selects items whose price attribute is greater than twice the numeric value of their discount attribute.
Entire node-sets can be combined ('unioned') using the vertical bar character |. Node sets that meet one or more of several conditions can be found by combining the conditions inside a predicate with 'or'.
v[x or y] | w[z] will return a single node-set consisting of all the v elements that have x or y child-elements, as well as all the w elements that have z child-elements, that were found in the current context.
Syntax and semantics (XPath 2.0)
[edit]Syntax and semantics (XPath 3)
[edit]Examples
[edit]Given a sample XML document
<?xml version="1.0" encoding="utf-8"?>
<Wikimedia>
<projects>
<project name="Wikipedia" launch="2001-01-05">
<editions>
<edition language="English">en.wikipedia.org</edition>
<edition language="German">de.wikipedia.org</edition>
<edition language="French">fr.wikipedia.org</edition>
<edition language="Polish">pl.wikipedia.org</edition>
<edition language="Spanish">es.wikipedia.org</edition>
</editions>
</project>
<project name="Wiktionary" launch="2002-12-12">
<editions>
<edition language="English">en.wiktionary.org</edition>
<edition language="French">fr.wiktionary.org</edition>
<edition language="Vietnamese">vi.wiktionary.org</edition>
<edition language="Turkish">tr.wiktionary.org</edition>
<edition language="Spanish">es.wiktionary.org</edition>
</editions>
</project>
</projects>
</Wikimedia>
The XPath expression
/Wikimedia/projects/project/@name
selects name attributes for all projects, and
/Wikimedia//editions
selects all editions of all projects, and
/Wikimedia/projects/project/editions/edition[@language='English']/text()
selects addresses of all English Wikimedia projects (text of all edition elements where language attribute is equal to English). And the following
/Wikimedia/projects/project[@name='Wikipedia']/editions/edition/text()
selects addresses of all Wikipedias (text of all edition elements that exist under project element with a name attribute of Wikipedia).
Implementations
[edit]Command-line tools
[edit]- XMLStarlet
- xmllint (libxml2)
- RaptorXML Server from Altova supports XPath 1.0, 2.0, and 3.0
- Xidel
C/C++
[edit]Free Pascal
[edit]- The unit XPath is included in the default libraries
Implementations for database engines
[edit]Java
[edit]- Saxon XSLT supports XPath 1.0, XPath 2.0 and XPath 3.0 (as well as XSLT 2.0, XQuery 3.0, and XPath 3.0)
- BaseX (also supports XPath 2.0 and XQuery)
- VTD-XML
- Sedna XML Database Both XML:DB and proprietary.
- QuiXPath,[11] a streaming open source implementation by Innovimax
- Xalan
- Dom4j
The Java
package javax.xml.xpath has been part of Java standard edition since Java 5[12] via the Java API for XML Processing. Technically this is an XPath API rather than an XPath implementation, and it allows the programmer the ability to select a specific implementation that conforms to the interface.
JavaScript
[edit]- jQuery XPath plugin[13] based on Open-source XPath 2.0 implementation in JavaScript[14]
- FontoXPath[15] Open source XPath 3.1 implementation in JavaScript. Currently under development.
.NET Framework
[edit]- In the System.Xml and System.Xml.XPath namespaces[16]
- Sedna XML Database
Perl
[edit]- XML::LibXML[17] (libxml2)
PHP
[edit]- Sedna XML Database
- DOMXPath[18] via libxml extension
Python
[edit]- The ElementTree XML API[19] in the Python Standard Library includes limited support for XPath expressions
- libxml2
- Amara
- Sedna XML Database
- lxml[20]
- Scrapy[21]
Ruby
[edit]Scheme
[edit]- Sedna XML Database
SQL
[edit]- MySQL supports a subset of XPath from version 5.1.5 onwards[22]
- PostgreSQL supports XPath and XSLT from version 8.4 onwards[23]
Tcl
[edit]- The tDOM package provides a complete, compliant, and fast XPath implementation in C[24]
Use in schema languages
[edit]XPath is increasingly used to express constraints in schema languages for XML.
- The (now ISO standard) schema language Schematron pioneered the approach.
- A streaming subset of XPath is used in W3C XML Schema 1.0 for expressing uniqueness and key constraints. In XSD 1.1, the use of XPath is extended to support conditional type assignment based on attribute values, and to allow arbitrary Boolean assertions to be evaluated against the content of elements.
- XForms uses XPath to bind types to values.
- The approach has even found use in non-XML applications, such as the source code analyzer for Java called PMD: the Java is converted to a DOM-like parse tree, then XPath rules are defined over the tree.
See also
[edit]Notes
[edit]- ^ XPath 2.0 supports atomic types, defined as built-in types in XML Schema, and may also import user-defined types from a schema.
- ^ XML authority Normal Walsh maintains an excellent online visualization of the axis specifiers.[7] It appears from the illustration that preceding, ancestor, self, descendant, and following form a complete, ordered, non-overlapping partition of document element tree.
- ^ For a complete description, see the W3C Recommendation document.
References
[edit]- ^ a b "XML and Semantic Web W3C Standards Timeline" (PDF). 2012-02-04. Archived from the original (PDF) on 2013-04-24. Retrieved 2012-02-04.
- ^ Bergeron, Randy (2000-10-31). "XPath—Retrieving Nodes from an XML Document". SQL Server Magazine. Archived from the original on 2010-07-26. Retrieved 2011-02-24.
- ^ Pierre Geneves (2012). "Course: The XPath Language" (PDF).
- ^ "XML Path Language (XPath) 3.0". World Wide Web Consortium (W3C). 2014-04-02. Retrieved 2021-07-16.
- ^ Kay, Michael (2012-02-10). "What's new in 3.0 (XSLT/XPath/XQuery) (plus XML Schema 1.1)" (PDF). XML Prague 2012. Retrieved 2021-07-16.
- ^ "XML Path Language (XPath) 3.1". World Wide Web Consortium (W3C). 2017-03-21. Retrieved 2021-07-16.
- ^ Walsh, Norman (1999). "Axis Specifiers". nwalsh.com. Personal blog of venerated XML sage graybeard. Retrieved 2021-02-25.
- ^ http://www.corefiling.com/opensource/pathan.html
- ^ "pugixml.org - Home". pugixml.org. Retrieved 2025-07-27.
- ^ "XQilla : HomePage". Archived from the original on 2015-05-18. Retrieved 2014-02-04.
- ^ "Google Code Archive - Long-term storage for Google Code Project Hosting". code.google.com. Retrieved 2025-07-27.
- ^ "javax.xml.xpath (Java SE 10 & JDK 10)". Java® Platform, Standard Edition & Java Development Kit Version 10 API Specification. Retrieved 2021-07-17.
Since: 1.5
- ^ "GitHub - ilinsky/jquery-xpath: jQuery XPath plugin (with full XPath 2.0 language support)". github.com. Retrieved 2025-07-27.
- ^ "GitHub - ilinsky/xpath2.js: xpath.js - Open source XPath 2.0 implementation in JavaScript (DOM agnostic)". github.com. Retrieved 2025-07-27.
- ^ "GitHub - FontoXML/fontoxpath: A minimalistic XPath 3.1 implementation in pure JavaScript". github.com. Retrieved 2025-07-27.
- ^ "System.Xml Namespace". Microsoft Docs. 2020-10-25. Retrieved 2021-07-16.
- ^ "XML::LibXML - Perl Binding for libxml2 - metacpan.org". metacpan.org. Retrieved 2025-07-27.
- ^ "PHP: DOMXPath - Manual". www.php.net. Retrieved 2025-07-27.
- ^ "xml.etree.ElementTree â — The ElementTree XML API — Python 3.13.5 documentation". docs.python.org. Retrieved 2025-07-27.
- ^ "lxml - Processing XML and HTML with Python". lxml.de. Retrieved 2025-07-27.
- ^
Duke, Justin (2016-09-29). "How To Crawl A Web Page with Scrapy and Python 3". Digital Ocean. Retrieved 2017-11-24.
Selectors are patterns we can use to find one or more elements on a page so we can then work with the data within the element. scrapy supports either CSS selectors or XPath selectors.
- ^ "MySQL :: MySQL 5.1 Reference Manual :: 12.11 XML Functions". dev.mysql.com. 2016-04-06. Archived from the original on 2016-04-06. Retrieved 2021-07-17.
- ^ "xml2". PostgreSQL Documentation. 2014-07-24. Retrieved 2021-07-16.
- ^ Loewer, Jochen (2000). "tDOM – A fast XML/DOM/XPath package for Tcl written in C" (PDF). Proceedings of First European TCL/Tk User Meeting. Retrieved 16 July 2021.
External links
[edit]- XPath 1.0 specification
- XPath 2.0 specification
- XPath 3.0 specification
- XPath 3.1 specification
- What's New in XPath 2.0
- XPath Reference (MSDN)
- XPath Expression Syntax (Saxon)
- XPath 2.0 Expression Syntax (Saxon), [1]
- XPath - MDC Docs by Mozilla Developer Network
- XPath introduction/tutorial
- XSLT and XPath function reference
XPath
View on GrokipediaIntroduction
Definition and Purpose
XPath is an expression language designed for addressing parts of an XML document, enabling the selection and computation of values such as strings, numbers, or Boolean values from the content and structure of XML data.[1] It provides a concise syntax to navigate and query XML documents, facilitating precise identification of elements, attributes, and other components without altering the underlying data.[1] The primary purpose of XPath is to select nodes, attributes, and text within the tree structure of XML documents, supporting applications such as document transformations via XSLT or declarative queries in XQuery.[1] By allowing users to specify paths and conditions, XPath enables efficient extraction and manipulation of information, making it a foundational tool for processing structured XML content in various XML-based technologies, including integration with standards like XML, XSLT, and XQuery.[2] At its core, XPath operates on a fundamental data model that represents an XML document as a tree of nodes, including types such as elements, attributes, text nodes, and others, while supporting XML Namespaces through expanded-names comprising a local part and namespace URI.[1] This tree-based model abstracts the hierarchical nature of XML, allowing expressions to traverse parent-child relationships and evaluate relative to a context that includes the current node, position, and available variables or functions.[1] XPath expressions are evaluated to yield results in one of four basic types: node-sets (collections of selected nodes), Booleans (true/false values), numbers (floating-point), or strings, depending on the operation performed.[1] This type system ensures flexible handling of query outcomes, from simple selections to computed values, all grounded in the document's node tree.[1]Relationship to XML Ecosystem
XPath emerged as a core component of the XML family of standards, developed by the World Wide Web Consortium (W3C) to address parts of XML documents, with its initial version (XPath 1.0) published as a W3C Recommendation in November 1999, shortly after XML 1.0 in 1998.[1] It originated from collaborative efforts by the XSL and XML Linking Working Groups to establish a shared syntax and semantics for functionality common to XSLT and XPointer.[1] Within the XML ecosystem, XPath serves essential roles in several key standards. In XSLT, it enables node selection for stylesheet matching and transformations, allowing precise targeting of document elements during XML processing.[1] In XQuery, XPath expressions function as predicates to filter and retrieve data from XML sources, forming the expressive foundation for querying structured documents.[6] Additionally, XPath supports addressing in XML Schema through identity constraints, where path expressions define uniqueness, keys, and references to ensure data integrity in schema validation.[7] XPath's operation depends on abstract data models for representing XML documents. Early versions, such as XPath 1.0, define an abstract data model that represents documents as trees of nodes, including a non-normative mapping to the XML Information Set (Infoset).[1] Subsequent versions, starting with XPath 2.0, utilize the XPath Data Model (XDM), an extension of the Infoset that incorporates schema awareness and supports values beyond just nodes, such as atomic types and sequences.[3] This dependency ensures XPath's compatibility across the ecosystem, including its use in XPointer for identifying XML fragments via query expressions.[1]History and Versions
Origins and Development
XPath emerged in the late 1990s as a key component of the World Wide Web Consortium's (W3C) efforts to standardize XML processing, specifically developed by the XSL Working Group to enable precise addressing of document elements within stylesheets.[1] The language was conceived to provide a compact, path-based mechanism for navigating and selecting parts of XML documents, addressing the need for a shared syntax between XSL Transformations (XSLT) for styling and the emerging XPointer framework for linking.[1] This initiative arose from the broader XML Activity at W3C, where the goal was to create a declarative expression language that operated on XML's logical tree structure without requiring full procedural programming.[1] The standardization process involved close collaboration between the XSL Working Group and the XML Linking Working Group, ensuring XPath's syntax and semantics could support both transformation and hyperlinking use cases.[1] Editors James Clark and Steve DeRose led the effort, drawing on the requirements for a non-XML syntax suitable for embedding in URIs and attributes.[1] Key motivations included simplifying XML navigation for stylesheet authors and link creators, allowing expressions to compute values like strings, numbers, or booleans from document content in a concise manner.[1] Development milestones began with the first Working Draft released on 21 April 1999, followed by revisions on 9 July, 13 August, and 8 October 1999, reflecting iterative refinements based on community feedback. These drafts focused on defining XPath's core location paths and expression capabilities while aligning with the evolving XML Infoset.[1] The process culminated in XPath 1.0 achieving W3C Recommendation status on 16 November 1999, marking its formal adoption as a foundational standard for the XML ecosystem.[1]XPath 1.0
XPath 1.0 was released as a W3C Recommendation on November 16, 1999.[1] The specification, titled "XML Path Language (XPath) Version 1.0," defines a language for addressing parts of an XML document, primarily designed for use by both XSLT and XPointer.[1] It models an XML document as a tree consisting of seven node types—root, element, attribute, namespace, processing instruction, comment, and text—and provides mechanisms to select nodes based on their relationships and properties.[1] The core innovations of XPath 1.0 include the introduction of location paths for navigating the document tree, node sets as the primary result type for selections, basic axis specifiers to define directional relationships (such as child, parent, or descendant), and predicates to filter results based on conditions.[1] These features established a compact syntax for node selection, enabling precise querying without requiring full document traversal in supporting technologies.[1] The language supports four basic data types—node-set, boolean, number, and string—along with a library of functions and operators for manipulation, such as arithmetic, comparison, and conversion operations.[1] XPath 1.0 quickly became the de facto standard for early XML processing, serving as a foundational component in standards like XSLT 1.0 and widely integrated into XML tools and libraries by the early 2000s.[8] Its adoption extended to major web browsers, including Internet Explorer 5.0 in 1999 via MSXML and subsequent implementations in Mozilla, Opera, Safari, and others, facilitating client-side XML transformations and queries.[9] This widespread use underscored its significance in enhancing XML interoperability and web functionality during the initial boom of XML technologies.[1] Despite its foundational role, XPath 1.0 has notable limitations, including the absence of sequences (relying instead on unordered node sets), weak typing without support for XML Schema data types, and a function library that primarily operates on strings with limited type-specific behaviors.[10] These constraints reflected the era's lack of schema awareness, as XML Schema development was just beginning at the time of its publication.[10]XPath 2.0
XPath 2.0 was published as a W3C Recommendation on January 23, 2007. This version represented a significant evolution from XPath 1.0, which was limited to unordered node sets, by adopting the XQuery 1.0 and XPath 2.0 Data Model (XDM).[3] The XDM introduced a more flexible structure comprising nodes, atomic values, and sequences, along with support for schema typing based on XML Schema.[11] These changes allowed XPath 2.0 to handle ordered collections of items, enabling expressions to return multiple values in a defined order rather than discarding duplicates as in prior versions.[3] Key advancements included dynamic typing for untyped data and integration with XQuery, which permitted embedding XPath 2.0 expressions within FLWOR (For-Let-Where-OrderBy-Return) constructs for more expressive querying. Atomic values, such as strings and integers, could now be manipulated independently of the XML tree, enhancing data processing capabilities without requiring full schema awareness in basic implementations.[11] However, the expanded feature set introduced notable challenges, including greater overall complexity. Conformance for XPath 2.0 processors requires support for the full language specification, with the static typing feature being optional; schema awareness is handled through the data model, and detailed conformance levels are defined in host languages such as XSLT 2.0 (basic, full, schema-aware) and XQuery 1.0.[12][13] The adoption of XPath 2.0 enabled more powerful and precise XML queries, particularly in environments requiring data integration with XQuery and XSLT 2.0.[3]XPath 3.0 and 3.1
XPath 3.0, released as a W3C Recommendation on 8 April 2014, was renamed from the earlier XPath 2.1 draft to align with the "3.0" family of specifications, including XQuery 3.0 and XSLT 3.0.[4] This version introduced significant enhancements to support functional programming paradigms, notably higher-order functions through inline function expressions and dynamic function calls, allowing functions to be treated as first-class citizens that can be passed as arguments, returned from other functions, or stored in variables.[14][15] These features built on XPath 2.0's sequences and type system by enabling more expressive and composable expressions for complex data processing.[4] XPath 3.1 followed as a W3C Recommendation on 21 March 2017, incorporating minor but impactful updates primarily to extend support for non-XML data structures.[2] Key additions included untyped arrays and maps in the XQuery and XPath Data Model (XDM) 3.1, facilitating JSON processing inspired by the JSONiq query language, with new expressions for constructing and manipulating these structures.[16][17] This alignment ensured stricter conformance with XQuery 3.1, promoting consistency across the XML query ecosystem while maintaining backward compatibility with prior XPath versions where applicable.[18] Since its stabilization in 2017, XPath 3.1 has remained the current standard, with implementations such as Saxon, Altova XMLSpy, and emerging engines like Xee providing growing support as of 2025, though adoption remains more limited compared to earlier versions due to the complexity of its advanced features.[2][19]Syntax and Semantics in XPath 1.0
Location Paths
Location paths in XPath 1.0 provide the primary mechanism for navigating and selecting nodes within an XML document tree, producing a node-set as the result.[20] They consist of one or more location steps separated by forward slashes (/ for child axes) or double forward slashes (// for descendant-or-self axes), allowing expressions to traverse hierarchical relationships from a context node.[20]
Absolute location paths begin with a leading slash (/), which selects the root node of the document as the initial context and applies the subsequent relative path from there.[20] In contrast, relative location paths do not start with a slash and operate from the current context node, making them flexible for use within larger expressions or transformations.[20] For instance, the absolute path / alone selects the document root, while a relative path like para selects all para element children of the current context node.[20]
Each location step within a path is composed of three main components: an axis specifier, a node test, and zero or more predicates enclosed in square brackets.[21] The axis specifier defines the direction of traversal (such as child:: or descendant::), the node test identifies the type or name of nodes to match (e.g., an element name like para or a node type like text()), and predicates filter the selected nodes based on additional conditions.[21] In unabbreviated syntax, a step appears as axis::node-test[predicate], though abbreviations like omitting child:: for the default child axis simplify common cases.[21]
Location paths are evaluated from left to right, with each step using the node-set produced by the previous step as its context.[21] The process begins by generating an initial node-set from the axis and node test relative to the context, then applies predicates to refine it, ensuring the result is an unordered node-set without duplicates.[21] For example, the path /child::para[position()=1] starts at the root, selects all para children, and filters to the first one in document order.[21] This stepwise, context-dependent evaluation enables precise selection of document portions for querying or processing.[20]
Axis Specifiers
Axis specifiers in XPath 1.0 define the direction and relationship of nodes relative to the context node within a location path, enabling precise navigation through the XML document tree.[1] Each axis represents a specific set of nodes that bear a particular relationship to the context node, such as children, ancestors, or siblings.[1] There are 13 axes in total: child, descendant, parent, ancestor, following-sibling, preceding-sibling, attribute, namespace, self, descendant-or-self, ancestor-or-self, following, and preceding.[1] Axes are classified as forward or reverse based on their traversal direction in document order. Forward axes include the context node or nodes that follow it in document order, such as child (direct children of the context node), descendant (all descendants excluding the context node), descendant-or-self (all descendants including the context node), attribute (attributes of the context node), namespace (namespace nodes of the context node), following (all nodes after the context node excluding descendants), following-sibling (all following siblings of the context node), and self (the context node itself).[1] Reverse axes, in contrast, include the context node or nodes that precede it in document order, comprising ancestor (all ancestors excluding the context node), ancestor-or-self (all ancestors including the context node), parent (the parent of the context node), preceding (all nodes before the context node excluding ancestors), and preceding-sibling (all preceding siblings of the context node).[1] The self axis is considered neutral, as it contains only the context node with no directional traversal.[1] If no axis is explicitly specified in a location step, the default axis is child, which simplifies common downward traversals.[1] Axes are used in the syntaxaxis::node-test, where axis names the relationship and node-test filters the selected nodes.[1] For instance, ancestor::chapter selects all ancestor elements named "chapter" from the context node.[1] This construct integrates into location steps to build paths, such as in expressions like child::para for selecting child paragraph elements.[1]
Each axis has a principal node type, which determines the primary kind of node it selects: element for most axes that can include elements (e.g., child, descendant), attribute for the attribute axis, and namespace for the namespace axis.[1] This principal type influences how nodes on the axis are ordered and processed during evaluation.[1]
| Axis | Direction | Principal Node Type | Description |
|---|---|---|---|
| child | Forward | Element | Direct children of the context node. |
| descendant | Forward | Element | All descendants of the context node, excluding itself. |
| parent | Reverse | Element | The parent of the context node. |
| ancestor | Reverse | Element | All ancestors of the context node, excluding itself. |
| following-sibling | Forward | Element | All siblings after the context node. |
| preceding-sibling | Reverse | Element | All siblings before the context node. |
| attribute | Forward | Attribute | Attributes of the context node. |
| namespace | Forward | Namespace | Namespace declarations of the context node. |
| self | Neutral | Varies | The context node itself. |
| descendant-or-self | Forward | Element | The context node and all its descendants. |
| ancestor-or-self | Reverse | Element | The context node and all its ancestors. |
| following | Forward | Element | All nodes after the context node in document order, excluding descendants. |
| preceding | Reverse | Element | All nodes before the context node in document order, excluding ancestors. |
Node Tests
In XPath 1.0, node tests serve as a mechanism within location steps to filter nodes along a specified axis by identifying their type or name, ensuring that only nodes matching the test are selected from the context node-set.[1] XPath 1.0 defines several node kinds that can be targeted through specific node tests: element nodes, attribute nodes, text nodes, comment nodes, processing-instruction nodes, and the universal node() test that matches all node types. For instance, the node testtext() selects text nodes, comment() selects comment nodes, and processing-instruction() selects processing-instruction nodes, optionally filtered by a literal name such as processing-instruction('xml-stylesheet'). The node() test is true for any node regardless of its kind. These tests are evaluated against the principal node type of the axis, which is typically element for forward axes like child or descendant, but attribute for the attribute axis.[1]
Name tests in XPath 1.0 allow selection based on a node's expanded name, using a QName in the syntax axis::QName, such as child::para to select child element nodes named "para" in no namespace. If the QName has a prefix, it is expanded using the in-scope namespace declarations from the expression context; an error occurs if the prefix is undeclared. The principal node type must match for the test to succeed, and the expanded name must equal that of the node.[1]
Wildcards provide flexibility in name tests: the asterisk * matches any node of the principal node type, regardless of local name or namespace, as in child::* to select all child elements. A namespace wildcard, formed as NCName:*, matches any node whose namespace URI corresponds to the prefix's URI, irrespective of the local name, such as html:* for elements in the HTML namespace. The default namespace does not apply to name tests.[1]
The formal syntax for node tests is NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')', where NameTest is either a QName or one of the wildcards * or NCName:*, and NodeType is one of comment, text, processing-instruction, or node. Evaluation of a node test is true if the node's kind and expanded name align with the test's criteria relative to the axis's principal node type; otherwise, it is false, effectively pruning non-matching nodes from the result set. Node tests are integral to location paths, combining with axis specifiers to navigate and select nodes in XML documents.[1]
Predicates
In XPath 1.0, predicates provide a mechanism to filter the nodes selected by a location step, allowing for more precise selection based on conditions evaluated against each potential node. They are enclosed in square brackets immediately following a node test in a location step, with the syntax[expression], where the expression is any XPath expression that evaluates to a boolean, number, or string value in the context of the current node.[1]
When evaluating a predicate, the context consists of the current node as the context node, the size of the node-set being filtered as the context size, and the position of the current node within that ordered node-set as the context position, which starts at 1 for the first node. The predicate expression is evaluated for each node in the input node-set produced by the preceding parts of the location step (axis and node test); only those nodes for which the expression evaluates to true are retained in the output node-set. The order of nodes in the context is determined by the axis direction—forward axes use document order, while reverse axes use reverse document order.[1]
The result of the predicate expression is converted to a boolean value to determine inclusion: if the expression yields a boolean, it is used directly; if numeric, it is true if the number equals the context position (e.g., [3] selects the third node in the context, equivalent to [position()=3]); if a string, it is converted to a boolean, where non-empty strings are true and the empty string is false (e.g., [*] selects all element nodes with non-empty string values). The built-in position() function returns the current context position, starting from 1, enabling predicates like [position()>1] to select all nodes except the first in the sequence.[1]
Multiple predicates can be chained in a single location step, applied sequentially to refine the node-set: each subsequent predicate operates on the filtered result of the previous one, updating the context node-set, size, and positions accordingly. For instance, employee[department="sales"][position()=1] first selects all employee nodes where the department attribute equals "sales," then from that subset, retains only the first node in document order. This sequential filtering allows complex selections without unions or conditionals within a single step.[1]
Functions and Operators
XPath 1.0 provides a set of built-in functions and operators that enable the manipulation and comparison of data within XML documents during path evaluation. These functions operate on primitive types such as node-sets, strings, booleans, and numbers, with specific rules for converting between them to ensure consistent behavior. For instance, when a node-set is used where a primitive type is expected, it is implicitly converted: to a boolean if non-empty (true) or empty (false); to a number via its string-value converted to a numeric value; or to a string using its string-value, which is the concatenation of all text node descendants in document order.[1] Functions in XPath 1.0 are categorized by the type of value they return and the arguments they accept, allowing for tasks like counting nodes, string manipulation, logical evaluation, and numeric computation. They can be invoked within location paths, predicates, or as standalone expressions, always returning a value of the specified type unless an error occurs, in which case the expression returns an empty node-set. Operators, meanwhile, perform set operations, arithmetic, comparisons, and logical evaluations, often promoting node-sets to primitives as needed for the operation.[1]Node-Set Functions
Node-set functions return a node-set or operate on node-sets to extract information, typically converting the input to a string or number for processing. Thelast() function returns the context size as a number, indicating the total number of nodes in the current context. The position() function returns the context position as a number, representing the index of the current node starting from 1. The count(node-set) function returns the number of nodes in the argument node-set. For example, count(//para) returns the total number of paragraph elements in the document. The id(object) function selects elements whose ID attribute matches tokens in the string value of the object, returning the corresponding node-set. The local-name(node-set?) function returns the local part of the expanded-name of the first node in the node-set (or the context node if no argument), or an empty string if none. Similarly, namespace-uri(node-set?) returns the namespace URI of the first node's expanded-name, and name(node-set?) returns the full QName.[1]
String Functions
String functions handle text manipulation, converting inputs to strings as necessary and returning string values. Thestring(object?) function converts its argument to a string: a node-set to the string-value of the first node, a number to its decimal representation, or a boolean to "true" or "false". The concat(string, string, ...) function concatenates two or more strings. The starts-with(string, string) function returns true if the first string begins with the second. The contains(string, string) function returns true if the first string contains the second as a substring. The substring-before(string, string) and substring-after(string, string) functions return the portion of the first string before or after the first occurrence of the second, respectively. The substring(string, number, number?) function extracts a substring starting at the specified position (1-based) with an optional length; for example, substring("12345", 2, 3) returns "234". The string-length(string?) function returns the number of characters in the string (or context node's string-value). The normalize-space(string?) function trims leading/trailing whitespace and replaces sequences of whitespace with a single space. The translate(string, string, string) function maps characters in the first string to those in the third based on positions in the second, replacing or removing as appropriate.[1]
Boolean Functions
Boolean functions evaluate conditions and return true or false. Theboolean(object) function converts its argument to a boolean: a non-empty node-set is true, a zero-length string or NaN number is false, and other values follow standard rules. The not(boolean) function inverts the boolean argument. The true() and false() functions return constant boolean values. The lang(string) function returns true if the context node's xml:lang attribute (or ancestor) matches the language code or a subcode of the argument.[1]
Number Functions
Number functions perform numeric operations, converting inputs to numbers where required. Thenumber(object?) function converts its argument to a double-precision floating-point number: node-sets via string-value, booleans to 1 or 0. The sum(node-set) function sums the numeric values derived from the string-values of the nodes. The floor(number) function returns the largest integer less than or equal to the argument. The ceiling(number) function returns the smallest integer greater than or equal to the argument. The round(number) function returns the integer closest to the argument, rounding .5 cases away from zero.[1]
Operators
Operators in XPath 1.0 include the union operator|, which combines two node-sets into one, removing duplicates and ordering by document order. Arithmetic operators +, -, * perform addition, subtraction, and multiplication on numbers (with node-sets converted via number()); div computes floating-point division, and mod yields the remainder from truncating toward negative infinity. Comparison operators =, !=, <, <=, >, >= compare values after converting node-sets to string-values for equality/inequality or to numbers for order, returning booleans; for node-sets, they evaluate true if there exists a pair of nodes where the condition holds. Logical operators and and or short-circuit: and returns false if the first operand is false, otherwise the effective boolean value of the second; or returns true if the first is true, otherwise the second. Implicit string conversion occurs when node-sets are operands in contexts expecting strings. These operators can be used in predicates or expressions to filter or compute results.[1]
Key Features of XPath 2.0
Sequences and Item Sequences
In XPath 2.0, a sequence is defined as an ordered collection of zero or more items, where each item is either a node or an atomic value from the XPath data model.[3] Sequences are flat and never nested, distinguishing them from more complex structures in later versions. An item sequence refers to this general ordered collection, while a node sequence is a specific subtype consisting solely of nodes; node sequences can be converted to item sequences but maintain their node-only composition unless atomized.[3] Sequences can be constructed using the comma operator (,), which concatenates the results of its operands into a single ordered sequence; for example, (1, "hello", /root) evaluates each part and combines them in order.[3] The union operator (|) combines two sequences by concatenating them and removing duplicates based on node identity for nodes or value equality for atomic values, as in //para | //chapter.[3] Functions such as distinct-values() further construct sequences by selecting unique items from an input sequence, preserving order while eliminating duplicates.[3]
During evaluation, XPath 2.0 path expressions and most operators return sequences rather than unordered sets, preserving the order of items as encountered and allowing duplicates unless explicitly removed via operations like union or distinct-values().[3] The context item, accessible via the . operator, represents a single item from the current sequence (or focus) used for relative path evaluations; if no context item is available, a dynamic error occurs.[3] This enables positional operations, such as slicing sequences with predicates like [position() > 2], which select items based on their order within the sequence.[3]
Compared to XPath 1.0's unordered node-sets, which could only contain nodes and ignored duplicates, XPath 2.0 sequences introduce ordering, support for atomic values alongside nodes, and the ability to process non-node items directly.[3] This shift provides a foundational mechanism for advanced data manipulation in expressions.[3]
Type System and Schema Awareness
XPath 2.0 introduces a robust type system derived from the XQuery 1.0 and XPath 2.0 Data Model (XDM), which supports both static and dynamic typing to enable precise manipulation of XML data.[3] The XDM defines two primary categories of items: atomic values and nodes. Atomic values are instances of atomic types from XML Schema, such asxs:string for textual data, xs:integer for whole numbers, xs:decimal for decimal numbers, xs:float and xs:double for floating-point values, xs:boolean for truth values, and xs:date or xs:time for temporal data, among others.[11] Nodes, including elements, attributes, text, and others, carry type annotations that indicate their schema-derived type, such as xs:untyped for unvalidated content or a specific complex type like customer if schema-validated.[11] This typing allows XPath expressions to operate on typed data, ensuring operations respect the underlying structure and constraints defined in XML Schema Part 2: Datatypes.[22]
Schema awareness in XPath 2.0 is optional and depends on the host language's conformance level, such as basic or schema-aware processing in XSLT 2.0 or XQuery 1.0.[23] In schema-aware mode, schemas can be imported to provide an in-scope schema definition for validation, enabling type annotations on nodes based on the Post-Schema-Validation Infoset (PSVI).[24] For instance, an element node might be annotated with a precise type like xs:integer if its content validates against a schema declaration, or fall back to xs:untypedAtomic for untyped atomic values in non-schema-aware contexts.[25] This awareness enhances query precision by allowing type-specific predicates and functions, while basic conformance treats all atomic values as xs:untypedAtomic without schema validation.[12]
XPath 2.0 supports type promotion and subtype substitution to facilitate flexible operations across compatible types. Numeric promotion automatically converts narrower numeric types to broader ones, such as promoting xs:integer to xs:double or xs:decimal to xs:float, ensuring arithmetic operations like addition or multiplication can proceed without explicit casting.[26] Subtype substitution permits a derived type, like a user-defined integer subtype, to be used wherever its base type xs:integer is expected, preserving type safety through inheritance hierarchies defined in XML Schema.[27] These mechanisms are applied during expression evaluation, particularly in function arguments and operator operands.
Functions and operators in XPath 2.0 are type-sensitive, adapting their behavior based on input types while leveraging promotion and substitution. For example, the sum() function computes the total of a sequence of numeric atomic values, such as a sequence of xs:integer items, by first promoting them to a common type like xs:double if necessary, and returns the result in that promoted type.[28] Similarly, comparison operators like = handle sequences by atomizing them to atomic values and applying type rules. Type mismatches trigger errors, such as XPTY0004 when attempting incompatible operations, like adding an xs:string to an xs:integer, ensuring runtime type safety.[29] This error handling promotes robust expression evaluation by halting execution on invalid type combinations.[30]
Expanded Functions and Operators
XPath 2.0 significantly expands the function library beyond XPath 1.0, introducing over 100 functions that support a broader range of data types and operations while maintaining backward compatibility for core functions from the earlier version, now extended to operate on sequences.[31][3] This enlargement enables more sophisticated data manipulation, particularly in integration with XQuery and XSLT 2.0, by providing built-in support for XML Schema types and sequence processing.[31] New categories of functions address previously unsupported domains, such as date and time handling. The date and time functions includecurrent-date(), which returns the current date in the system's default timezone as an xs:date, and year-from-date(), which extracts the year component from a date value.[31] Duration functions complement this by manipulating time intervals, for example, years-from-duration() decomposes a duration into its year component.[31] QName functions facilitate working with qualified names, such as resolve-QName(), which constructs a QName from a lexical representation using the in-scope namespaces.[31] Similarly, anyURI functions like resolve-uri() combine a relative URI with a base URI to produce an absolute URI.[31]
Analytic functions operate on sequences to perform aggregation and selection tasks. For instance, index-of($sourceSequence, $searchItem) returns a sequence of integers representing the positions of occurrences of the search item within the source sequence.[31] distinct-values($arg) eliminates duplicate items from a sequence, preserving order of first occurrences.[31] Aggregation functions such as avg($arg) compute the arithmetic mean of numeric values in a sequence, while max($arg) and min($arg) return the maximum and minimum values, respectively, supporting numeric, date, and string types with appropriate collations.[31]
String functions gain advanced capabilities, notably regular expression support. analyze-string($input, $pattern) breaks a string into matching and non-matching substrings based on a regex pattern, returning an analyzed structure.[31] tokenize($input, $pattern) splits a string into a sequence of substrings using a delimiter pattern.[31] replace($input, $pattern, $replacement) substitutes matches of a regex pattern with a replacement string, and matches($input, $pattern) tests whether the input contains a match for the pattern.[31] These functions leverage flags for case sensitivity and multiline processing, enhancing text processing precision.[31]
XPath 2.0 introduces specialized operators for value comparisons, arithmetic, ranges, and type assertions. The value comparison operators—eq, ne, lt, le, gt, and ge—perform order-sensitive comparisons on atomized atomic values, returning a boolean after type promotion or subtype substitution.[3] For example, $price gt 10 evaluates to true if the atomized price exceeds 10.[3] The to operator generates a sequence of consecutive integers, as in 1 to 5, which yields the sequence (1, 2, 3, 4, 5).[3] The idiv operator provides integer division, truncating toward zero, such as 17 idiv 5 resulting in 3.[3] The treat as expression asserts a type without conversion, raising an error if the value does not conform, for instance, ($value treat as xs:integer) ensures integer compatibility.[3] These operators extend XPath 1.0's capabilities, with compatibility mode allowing limited use of legacy general comparisons.[3]
Path Expressions Enhancements
XPath 2.0 introduced significant enhancements to path expressions, building upon the location paths of XPath 1.0 by enabling more flexible navigation and manipulation of node sequences through integration with the language's sequence type system. These improvements allow expressions to operate directly on sequences of items, facilitating conditional logic, quantification, set operations, and grouping within paths, which extends the expressive power for querying XML documents without relying on external host languages. One key enhancement is the support for relative paths applied to sequences, where path steps can be evaluated against each item in a sequence, producing a new sequence of results. For instance, given a sequence of nodes, a relative path like/child::para can be applied to each, yielding concatenated results from all items, which contrasts with XPath 1.0's restriction to single-node contexts. This enables more dynamic navigation, such as selecting attributes from multiple elements in a single expression.
Conditional expressions using if-then-else provide branching logic within paths, allowing dynamic selection based on node properties. The syntax if (test) then result1 else result2 evaluates the boolean test and returns the appropriate sequence, as in if (@type = 'odd') then 'odd' else 'even', which can be embedded in predicates or steps to refine path outcomes. This feature supports complex filtering, such as conditionally including nodes based on attribute values or computed conditions.
Quantified expressions introduce universal and existential quantification with some and every, enabling assertions over sequences in path predicates. The form some $var in sequence satisfies boolean-expression or every $var in sequence satisfies boolean-expression returns true if the condition holds for at least one or all items, respectively; for example, every $p in //para satisfies $p/@id verifies that all paragraphs have an ID attribute. These are particularly useful for validating structural patterns in documents during path evaluation.
Set operations on sequences extend union with the familiar | operator, while introducing intersect and except for intersection and difference, respectively, all of which operate on ordered sequences to produce new sequences without duplicates. For example, (//chapter | //appendix) intersect //section selects sections that are either chapters or appendices. These operators enhance path expressions by allowing combinatorial selection from multiple node sets.
Parenthesized expressions permit grouping to control evaluation order and apply predicates or filters to intermediate results, such as (//para)[1] to select the first paragraph in the document, overriding default document order. This grouping mechanism ensures precise control in complex paths, preventing unintended expansions of steps.
Innovations in XPath 3.0 and 3.1
XPath 3.0 introduced the simple map operator (!), allowing expressions like //book ! title to map titles from book nodes. XPath 3.1 added the arrow operator (=>) for chaining, e.g., //book => title(), and the lookup operator (?) for maps and arrays, enhancing path-like navigation for non-XML data.[4][2]
Higher-Order Functions
XPath 3.0 introduces functions as first-class citizens within the XPath data model, treating them as function items that can be passed as arguments to other functions, returned as results, or stored in variables.[32] This advancement enables functional programming paradigms by allowing functions to be manipulated like any other value in sequences, building upon the sequence handling introduced in XPath 2.0.[33] Function items are identified by their name, arity (number of parameters), and type signature, and they represent executable code that can be invoked dynamically.[34] Anonymous functions, also known as inline functions, can be defined directly within expressions using the syntaxfunction($parameter) { body }, where parameters are declared with optional type annotations and the body contains the function's logic.[14] These allow for concise, on-the-fly function creation without needing a separate declaration. Partial application is supported by constructing new functions that fix some arguments of an existing function, such as function($y) { fn:concat("Hello", $y) }, which partially applies the fn:concat function with "Hello" as the first argument.[35] Named functions, typically user-defined in XQuery modules, can be referenced and invoked within XPath expressions using named function references like fn:myFunction#2, promoting reusability across XPath and XQuery contexts.[36]
Higher-order functions in XPath 3.0 and 3.1 accept function items as parameters to operate on sequences, facilitating operations like transformation, selection, and aggregation. The fn:map function applies a given function to each item in a sequence, producing a new sequence of results; for example, fn:map(function($x) { $x * $x }, (1 to 5)) returns (1, 4, 9, 16, 25), squaring each integer.[37] Similarly, fn:filter selects items from a sequence where a predicate function returns true, as in fn:filter((1 to 10), function($x) { $x mod 2 eq 1 }), which yields the odd numbers (1, 3, 5, 7, 9).[38] For accumulation, fn:fold-left iteratively applies a function from left to right starting from an initial value, such as fn:fold-left((10, 20, 30), 0, function($acc, $item) { $acc + $item }), resulting in 60.[39] The fn:fold-right variant processes from right to left, useful for operations like building reversed structures.[40] These functions, along with others like fn:map-pairs, extend XPath's expressiveness for complex data processing without explicit loops.[41]
Maps, Arrays, and JSON Support
XPath 3.1 introduces maps and arrays as new item types in the data model to facilitate processing of structured data, particularly JSON objects and arrays.[2] Maps represent unordered collections of key-value pairs, where keys are atomic values such as strings or integers, and values can be any sequence of items. Arrays, in contrast, are ordered sequences of zero or more members, providing indexed access similar to lists. These types extend XPath's capabilities beyond XML nodes, enabling direct querying and manipulation of non-XML data without prior conversion.[16][42] Maps are constructed using the syntaxmap { key: value, ... }, allowing dynamic creation of key-value structures. For example, map { "name": "Alice", "age": 30 } produces a map with string keys "name" and "age" mapping to the respective string and integer values. Access to map entries occurs via the dynamic key accessor ?key, such as $m?age which retrieves 30 from the example map. To retrieve all entries, the wildcard accessor ?* returns a sequence of key-value pairs, while ?(key1, key2) allows access to multiple specified keys in a single expression.[43][44][45]
Arrays are constructed with square brackets, as in [1, 2, 3], yielding an ordered array of integer members. Members are accessed positionally using ?n, where n is a positive integer starting from 1; for instance, $a?2 returns 2 from the example array. XPath 3.1 provides a suite of array functions for common operations, including array:join to concatenate multiple arrays into one and array:sort to order members based on a collation or comparison function. These functions support efficient manipulation, such as joining nested arrays or sorting heterogeneous content.[46][44][47][48]
Integration with JSON is achieved through dedicated functions that bridge textual JSON and XPath's data model. The parse-json function converts a JSON string into a map or array; for example, parse-json('{"name": "Alice", "scores": [90, 85]}') yields a map containing a nested array. Conversely, json-to-xml transforms maps and arrays into an XML representation, useful for hybrid processing in XML-centric environments, with options to control formatting and escaping. XPath 3.1 also introduces untyped maps and arrays, which do not require schema validation and treat atomized values as xs:untypedAtomic, enhancing flexibility for processing arbitrary JSON without predefined types.[49][50][16]
Additional Language Features
XPath 3.1 introduces the arrow operator (=>) to enable concise function chaining by applying a function to the result of a preceding expression, supplying the result as the first argument to the subsequent function. This syntactic enhancement improves readability for sequential operations, such as transforming a value through multiple functions without nested parentheses. For instance, the expression "abc" => substring(2, 1) => upper-case() evaluates to "B", where the substring operation extracts the second character, and upper-case then converts it to uppercase.[51]
The format-number function in XPath 3.1 receives enhancements through configurable decimal formats in the static context, enabling locale-sensitive number formatting with picture strings. Properties like decimal-separator, grouping-separator, and zero-digit can be customized via named decimal formats, allowing patterns such as format-number(1234.56, "#,##0.00") to produce "1,234.56" using comma grouping and two decimal places. This supports international variations, such as European formats with comma decimals, by declaring formats like declare decimal-format decimal-separator="," grouping-separator=".".[52]
Namespace declarations in XPath 3.1 expressions use EQNames for qualified references, supporting both prefix-based syntax (e.g., my:invoice after declaring my to a URI) and URI-qualified names (e.g., Q{http://example.com/ns}invoice) to avoid prefix dependencies. The static context includes statically known namespaces mapping prefixes to URIs, ensuring unambiguous resolution in expressions involving qualified names for elements, attributes, or functions. This explicit handling maintains compatibility while allowing context-free namespace usage in portable expressions.[53]
Backward Compatibility and Conformance
XPath 3.1 is designed as a fully compatible extension of XPath 3.0, ensuring that all valid expressions from XPath 3.0 remain valid and produce the same results in XPath 3.1, with the addition of new features like support for untyped JSON structures via maps and arrays that do not introduce breaking changes.[2] Similarly, XPath 3.0 extends XPath 2.0 without invalidating prior syntax, maintaining interoperability across versions while evolving the underlying data model. In XPath 2.0, the concept of node-sets from XPath 1.0 was replaced by sequences—ordered collections of items that can include nodes, atomic values, or functions—allowing more flexible processing, though all XPath 1.0 and 2.0 path expressions and syntax remain valid in later versions.[3] To support legacy applications, XPath includes a compatibility mode in its static context specifically for XPath 1.0, which, when enabled, adjusts behaviors such as type conversions in function arguments and general comparisons to mimic XPath 1.0 semantics, ensuring nearly all XPath 1.0 expressions yield equivalent results.[54] This mode is set tofalse by default in host languages like XQuery 3.1 to enforce stricter modern semantics, but it can be activated for backward compatibility.[55]
Conformance to XPath 3.x is defined primarily through host languages such as XQuery 3.1 and XSLT 3.0, which specify required core features—including path expressions, core functions, and the sequence data model—and optional features like schema awareness (for type checking against XML Schema), higher-order functions (for passing functions as arguments), and serialization options.[56] A minimally conforming processor must support all mandatory features of XPath 3.1, while optional features allow implementations to declare varying levels of support, such as basic (without schema) versus schema-aware processing.[57]
The updates in XPath 3.1 are minor and non-disruptive, primarily enhancing JSON handling by introducing untyped maps and arrays that integrate seamlessly with existing sequence-based expressions, without altering the semantics of prior XPath constructs.[58] Processors must declare their supported XPath version and features through the static context, which includes components like the XPath version, compatibility mode, and in-scope namespaces, enabling host environments to configure evaluation accordingly.[54] This declaration mechanism ensures predictable behavior and facilitates testing via implementation reports, such as those for XQuery 3.1, which validate conformance across vendors.[59]
As of November 2025, work is ongoing on XPath 4.0, currently in W3C Working Group Review Draft stage (dated 11 November 2025), building on 3.1 features.[60]
Examples
XPath 1.0 Examples
XPath 1.0 provides a concise syntax for navigating and selecting nodes within XML documents, primarily resulting in node-sets. Examples below demonstrate fundamental location paths, predicates, axes, and functions, evaluated against a sample XML document modeling a simple book structure. Consider the following XML document:<book>
<chapter id="intro">
<title>Introduction</title>
<para>This is the first paragraph.</para>
<para>This is the second paragraph.</para>
<ul>
<li>First item</li>
<li>Second item</li>
</ul>
<h1>Main Heading</h1>
</chapter>
<chapter id="main">
<title>Main Chapter</title>
<para>Another paragraph.</para>
</chapter>
</book>
<book>
<chapter id="intro">
<title>Introduction</title>
<para>This is the first paragraph.</para>
<para>This is the second paragraph.</para>
<ul>
<li>First item</li>
<li>Second item</li>
</ul>
<h1>Main Heading</h1>
</chapter>
<chapter id="main">
<title>Main Chapter</title>
<para>Another paragraph.</para>
</chapter>
</book>
//title selects all <title> element nodes in the document, yielding a node-set containing both "Introduction" and "Main Chapter" titles.[1]
Predicates refine selections by applying conditions; for instance, //chapter[@id='intro']/para[1] selects the first <para> child of the <chapter> element with id attribute equal to "intro", returning the node-set with "This is the first paragraph."[1]
Axes enable navigation along specific directions in the node tree; the expression preceding::para[1], evaluated from the second <para> in the introductory chapter, selects the immediately preceding <para> node in document order, which is the first paragraph.[1]
XPath 1.0 includes core functions for manipulating node-sets and values; the expression count(//li) returns the number 2, counting all <li> elements, while string-length(name(//h1)) returns the number 2, as name(//h1) yields "h1" and its string length is 2—combining them as count(//li) + string-length(name(//h1)) evaluates to the number 4.[1]
XPath 2.0 and 3.1 Examples
XPath 2.0 introduced sequences, allowing the construction of ordered collections of items that can include nodes, atomic values, or mixtures thereof, enabling more flexible data manipulation than the node-set model of XPath 1.0.[61] For instance, consider an XML document representing a book with paragraphs and lists; the expression(//para, //list)[position() mod 2 = 1] constructs a sequence by concatenating all <para> and <list> elements in document order, then selects every odd-positioned item in that sequence (starting from position 1).[62][63] This filters to include, for example, the first <para>, the first <list>, the third <para>, and so on, demonstrating positional predicates on sequences.[64]
XPath 2.0 also added schema awareness and type checking, permitting operations on typed values from XML Schema.[65] In a sample XML catalog of items with <price> elements, some containing strings like "10.50" and others non-numeric text, the expression sum(//price[. castable as xs:decimal]) first filters the <price> nodes where the string value can be cast to xs:decimal, then computes their numeric sum, ignoring uncastable items to avoid errors.[66][28] This yields, for example, 25.75 if valid prices are "10.50" and "15.25", highlighting safe aggregation over potentially heterogeneous data.[67]
XPath 3.1 extended higher-order functions, treating functions as first-class values for dynamic invocation and composition.[68] For a book XML with <chapter> elements each containing <para> subelements, the expression fold-left(//chapter, 0, function($c, $acc) { $acc + count($c/para) }) initializes an accumulator at 0 and iteratively adds the count of <para> children from each chapter, resulting in the total number of paragraphs across all chapters, such as 42 for a document with chapters having 10, 15, and 17 paragraphs respectively.[69] This functional approach enables concise accumulation without explicit loops.[70]
XPath 3.1 introduced native support for JSON processing via maps and arrays in the data model.[71] Given a JSON string {"name": "Bob", "age": 30}, the expression parse-json('{"name": "Bob", "age": 30}')?name parses it into a map and accesses the value for the key "name" using the single-question-mark operator, returning the string "Bob" or an empty sequence if the key is absent.[16][49] This facilitates direct querying of JSON structures alongside XML.[72]
Error handling in XPath 3.1 uses try-catch to manage dynamic errors gracefully.[73] The expression try { 1 div 0 } catch * { "error" } attempts division by zero, which raises an error, but catches any error type (denoted by *) and returns the string "error" instead, preventing query failure in broader contexts.[74] This is useful for robust expressions in environments like XQuery where partial results are preferable to total failure.[75]
Implementations
Command-Line Tools
Several command-line tools enable the evaluation of XPath expressions directly on XML documents without requiring integration into a programming environment. These utilities are particularly useful for ad-hoc queries, validation, and extraction tasks in shell scripts or development workflows.[76] XMLStarlet is an open-source toolkit that includes thesel command for selecting and extracting data using XPath expressions. It supports XPath 1.0 and processes XML files via libxml2. A typical command to output the value of all <title> elements is xmlstarlet sel -t -v "//title" file.xml, which prints the results as plain text.[77][78]
xmllint, part of the libxml2 library, provides a --xpath option to evaluate XPath 1.0 expressions on XML input. For instance, xmllint --xpath "//book/title" document.xml serializes matching nodes, such as all <title> elements under <book>, or reports an empty set if no matches are found. The tool outputs full node serializations for nodesets, with results encoded according to the document's specifications.[79][79]
Saxon-HE, a Java-based open-source processor from Saxonica, supports XPath up to version 3.1 and can evaluate expressions via its command-line interface, often by embedding them in a minimal XSLT stylesheet. For example, create a file query.xsl containing <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="/"><xsl:value-of select="//title"/></xsl:template></xsl:stylesheet>, then run java -jar saxon-he-12.9.jar -s:file.xml -xsl:query.xsl to extract and output the values as text. This approach leverages Saxon's full XSLT 3.0 capabilities for more complex XPath usage.[80][81]
Most of these tools, including XMLStarlet and xmllint, are limited to XPath 1.0, while Saxon-HE extends to 3.1; support for intermediate versions like 2.0 varies. Output formats differ, with options for plain text, XML serialization, or error reporting, but advanced features such as higher-order functions in XPath 3.1 are typically unavailable outside Saxon.[77][79][80]
Common use cases include quick testing of XPath expressions during development, extracting data for reports in automation scripts, and integrating into Unix pipelines for XML processing tasks.[76]
Libraries in Programming Languages
In Java, the standardjavax.xml.xpath package, part of the Java API for XML Processing (JAXP), provides an object-model neutral API for evaluating XPath 1.0 expressions against XML documents.[82] The Saxon library, developed by Saxonica, offers comprehensive support for XPath up to version 3.1, including advanced features like higher-order functions and JSONiq extensions, through its s9api interface and JAXP compatibility.[83] In contrast, the Xalan-Java library from Apache primarily supports XPath 1.0 with partial compatibility for some XPath 2.0 features, but lacks full conformance to later versions.[84]
For JavaScript, the native XPathEvaluator interface in web browsers implements XPath 1.0 as part of the DOM standard, allowing evaluation of expressions on XML or HTML documents within the browser environment. Saxon-JS, a JavaScript port of the Saxon processor, enables XPath 3.1 support in browsers via WebAssembly or Node.js, providing access to modern features like maps and arrays through a dedicated runtime library.[85]
Python developers commonly use the lxml.etree module, which binds to the libxml2 library and supports XPath 1.0 evaluation with extensions for namespace handling and custom functions.[86] For XPath 3.1 capabilities, the Saxon/C API via the saxonche package integrates Saxon's full feature set, including schema-aware processing and higher-order functions, into Python applications.[87]
In the .NET framework, System.Xml.XPath classes provide built-in support for XPath 1.0, enabling navigation and querying of XML data through navigators and expression compilation. Saxon.NET, the .NET port of Saxon, delivers complete XPath 3.1 conformance, with APIs for compiling expressions and handling namespaces in both .NET Framework and .NET Core environments.[88]
Other languages include PHP's DOMXPath class, which implements XPath 1.0 on DOM trees with support for namespace prefixes via libxml.[89] In Perl, XML::XPath offers a pure-Perl implementation of XPath 1.0 for parsing and querying, while XML::LibXML provides XPath 1.0 support through bindings to libxml2, including context-aware evaluation.
Across these libraries, a common pattern involves APIs for compiling XPath expressions into reusable objects for efficient repeated evaluation, often with methods to declare namespaces explicitly to resolve prefixes in queries against namespaced XML. Some libraries, such as Saxon variants, also offer command-line wrappers for testing expressions outside of code.[83]
Integrations in Databases and Query Engines
XPath has been integrated into various relational and native XML databases to enable querying and manipulation of XML data stored within them. These integrations often combine XPath with SQL or native query languages to support hybrid queries, allowing users to navigate XML structures alongside traditional relational data. Key features include dedicated XML data types for storage, indexing of XPath expressions for performance, and functions that evaluate XPath paths to extract nodes, values, or fragments. Such support facilitates applications like document management, data integration, and reporting on semi-structured data.[90] Microsoft SQL Server provides support for a subset of XPath 2.0 (via XQuery 1.0) through its xml data type, which stores XML instances and enables querying via methods like .query() and .value(). The .query() method evaluates an XPath expression (embedded in XQuery) against an XML instance, returning an XML fragment of the selected nodes. For scalar extraction, the .value() method retrieves a single value from the XML using an XPath path, converting it to a SQL type like string or integer. These methods support indexed XML columns for efficient path-based retrieval in large datasets. SQL Server also allows hybrid SQL/XML queries, combining XPath results with relational joins.[91][92] PostgreSQL offers XPath 1.0 integration via the xml data type and the xpath() function, which evaluates an XPath expression on an XML value and returns an array of matching XML nodes. This enables extraction of elements, attributes, or text from stored XML documents within SQL queries. PostgreSQL's core support is limited to XPath 1.0, with deprecated extensions like xml2 (deprecated since version 8.3) providing additional XPath 1.0 functions and XSLT transformations. XML storage in PostgreSQL supports basic indexing, though full path indexing requires custom configurations, and hybrid queries blend XPath results with SQL operations for relational-XML processing.[93][94] BaseX, a native XML database and XQuery processor, provides full XPath 3.1 support as part of its native XQuery 3.1 implementation. This allows complex path expressions, including maps, arrays, and JSONiq extensions, directly on stored XML collections. BaseX optimizes XPath queries through its indexing system, which precomputes paths, full-text terms, and structural indexes for rapid evaluation. It supports hybrid querying by embedding XPath within XQuery modules that can interact with external data sources. eXist-db, another native XML database, integrates XPath 3.1 via its XQuery 3.1 engine, enabling full W3C-compliant path navigation on stored documents. It features advanced indexing for XPath expressions, including range indexes on node values and structural indexes for ancestor-descendant relationships, which accelerate query performance on large collections. eXist-db's full-text support extends XPath with Lucene-based search, allowing combined path and keyword queries. Hybrid capabilities arise from its RESTful API and XQuery extensions for integrating with relational data.[95] Oracle Database incorporates XPath 1.0 through the XMLType data type and the extract() function, which selects nodes matching an XPath expression from an XML instance, returning an XMLType result. For more advanced querying, Oracle supports XQuery (version 1.0, with XPath 2.0 features) via functions like XMLQuery(), enabling XPath-embedded expressions for complex extractions and transformations. XMLType supports structured and unstructured storage with path-based indexing via XML indexes, optimizing XPath performance. Hybrid SQL/XML queries in Oracle combine XPath results with relational predicates, such as in XMLTable for tabular output.[90][96]Applications in Standards
Use in XSLT and XQuery
XPath plays a central role in XSLT by providing the expression language for selecting and manipulating nodes during XML transformations. In XSLT, XPath expressions are used in attributes such as thematch attribute of the <xsl:template> element to define patterns that identify nodes in the source document for processing, enabling rule-based transformations. For instance, <xsl:template match="/doc/item"> targets all item elements under the root /doc. Similarly, the select attribute in elements like <xsl:value-of> extracts values from nodes using XPath, such as <xsl:value-of select="@price"/> to output an attribute's string value. These mechanisms allow XSLT to navigate the XML tree structure efficiently while the stylesheet language handles the overall transformation logic.[97]
Version alignment between XSLT and XPath ensures compatibility in feature sets and data models. XSLT 1.0 exclusively uses XPath 1.0, limiting expressions to basic node selection and simple functions suitable for early XML processing needs. In contrast, XSLT 3.0 is built on XPath 3.0 but supports XPath 3.1 as an implementation option, incorporating advanced features like higher-order functions, maps, and arrays for more sophisticated transformations. This progression enables XSLT processors to handle complex data structures beyond traditional XML, such as streaming large documents or integrating JSON-like data.[98][97]
In XQuery, XPath expressions serve as the foundational syntax for querying XML documents, either standalone or embedded within more complex constructs. Standalone XPath queries, like /doc//item, can directly retrieve node sets, while integration in FLWOR (For-Let-Where-Order by-Return) expressions adds procedural flow; for example, for $node in /doc//item return $node/@name iterates over items and returns their name attributes, facilitating filtering, sorting, and aggregation. XQuery 3.1 fully incorporates XPath 3.1, extending the language with native support for JSON processing through maps and arrays—features that build on JSONiq extensions to query hybrid XML-JSON datasets seamlessly.[6]
The synergy between XPath, XSLT, and XQuery enhances XML ecosystem capabilities: XPath supplies precise addressing and path-based navigation, while XSLT focuses on declarative transformations and XQuery on functional querying with iteration and conditionals. This division allows developers to compose transformations (via XSLT) and queries (via XQuery) that leverage XPath's core for efficient data access, reducing redundancy and improving expressiveness in applications like document conversion and database retrieval.[2]
Role in Schema Languages and Validation
XPath plays a central role in schema languages that extend XML validation beyond structural grammars, enabling declarative rules for semantic constraints. In Schematron, an ISO standard for rule-based validation (ISO/IEC 19757-3:2020), XPath expressions form the core of assertions and reports that check for the presence or absence of patterns in XML documents.[99] For instance, an assertion like<assert test="count(para) > 0">Every section must contain at least one paragraph.</assert> uses an XPath predicate to evaluate whether a <section> element has more than zero <para> children, reporting a violation if the condition fails.[100] This approach allows Schematron to handle complex, non-local constraints that grammar-based schemas cannot express, such as cross-document references or conditional requirements.[101]
RELAX NG, a schema language standardized by OASIS, supports key and ID uniqueness constraints through embedded Schematron annotations, leveraging XPath for these checks since its core specification lacks native identity constraint support.[102] By embedding Schematron rules within RELAX NG elements (ignored by the RELAX NG processor but processed separately), validators can apply XPath expressions to enforce uniqueness, such as <rule context="item"><assert test="not(@key = preceding-sibling::item/@key)">Keys must be unique.</assert></rule>, ensuring no duplicate attribute values across sibling elements.[103] This integration combines RELAX NG's pattern-matching for structure with XPath-driven rules for data integrity, processed during validation to select and test relevant XML instances.[104]
In XML Schema 1.1 (XSD 1.1), defined by the W3C, XPath 2.0 expressions enable advanced features like conditional type assignment and assertions, allowing dynamic validation based on instance content.[105] For conditional type assignment, an <xs:alternative> element uses an XPath 2.0 test attribute, such as test="@country = 'US'", to assign a specific type (e.g., US-specific address format) if the condition holds, otherwise falling back to a default type.[105] Assertions, declared in complex types via <xs:assert>, similarly employ XPath 2.0 to enforce rules like test="if (@age > 18) then parent::person/@guardian = '' else true()", validating relationships within the element's subtree.[105]
XForms, a W3C recommendation for web forms, relies on XPath for model constraints and UI bindings, ensuring data validity during form processing. In the model section, <bind> elements use XPath expressions for constraints like constraint="floor(@age) >= 18", which binds to instance data and evaluates to restrict invalid values, or for calculating derived values via calculate="sum(children::* / @price)". Bindings to form controls, such as ref="instance('data')/address/city", select nodes using XPath, integrating validation seamlessly into the form's instance data model.[106]
Across these schema languages, the validation process involves XPath to select target XML instances (e.g., via context paths in rules or binds), evaluate predicates or expressions against them, and report violations if conditions fail, often generating detailed diagnostics for non-conformance.[100] This XPath-centric mechanism supports modular, extensible validation pipelines, where rules are applied post-structural parsing to verify semantic correctness.[105]