XSLT - Dynamic XPath Evaluation Using <xsl:evaluate> in XSLT 3.0
Introduction
In normal XSLT programming, XPath expressions are written directly inside the stylesheet. For example, if you want to select all book elements, you can write:
<xsl:apply-templates select="book"/>
Here, the XPath expression book is known when the stylesheet is written and compiled.
However, sometimes an XSLT application needs to determine the XPath expression at runtime. The expression might come from an XML configuration file, a parameter, a database, or another external source. In such situations, writing the XPath expression directly into the stylesheet is not possible because the required expression is not known in advance.
XSLT 3.0 provides the <xsl:evaluate> instruction for this purpose. It allows an XPath expression represented as a string to be dynamically compiled and evaluated during the transformation.
What Is <xsl:evaluate>?
<xsl:evaluate> is an XSLT 3.0 instruction used to evaluate an XPath expression that is constructed dynamically.
Consider the following XML:
<catalog>
<book category="programming">
<title>Learning XML</title>
<price>40</price>
</book>
<book category="database">
<title>SQL Fundamentals</title>
<price>35</price>
</book>
<book category="programming">
<title>XSLT in Practice</title>
<price>50</price>
</book>
</catalog>
Suppose the XPath expression is stored in a variable:
<xsl:variable name="expression" select="'book[@category = "programming"]'"/>
The value of $expression is a string containing an XPath expression. It is not automatically treated as XPath code.
<xsl:evaluate> allows that string to be evaluated as an XPath expression:
<xsl:evaluate xpath="$expression"/>
The processor dynamically evaluates:
book[@category = "programming"]
and obtains the matching book elements.
Why Is <xsl:evaluate> Needed?
Without <xsl:evaluate>, XPath expressions generally need to be known when the stylesheet is created.
For example:
<xsl:apply-templates select="book[@category='programming']"/>
This works when the condition is fixed.
But imagine that the user can enter one of the following expressions:
book[@category='programming']
or:
book[price > 40]
or:
book[contains(title, 'XML')]
The stylesheet cannot know beforehand which expression will be selected.
Instead, the expression can be stored in a variable:
<xsl:param name="user-expression"/>
Then:
<xsl:evaluate xpath="$user-expression"/>
allows the stylesheet to evaluate the selected expression dynamically.
This makes <xsl:evaluate> useful for configurable transformation systems.
Basic Syntax
A simplified form is:
<xsl:evaluate xpath="expression"/>
The xpath attribute supplies the expression that should be evaluated.
For example:
<xsl:variable name="path" select="'catalog/book/title'"/>
<xsl:evaluate xpath="$path"/>
The variable contains the string:
catalog/book/title
The processor evaluates that string as an XPath expression.
Complete Example
Consider this XML:
<students>
<student>
<name>John</name>
<marks>85</marks>
</student>
<student>
<name>Mary</name>
<marks>72</marks>
</student>
<student>
<name>David</name>
<marks>91</marks>
</student>
</students>
Suppose the stylesheet receives an XPath expression as a parameter:
<xsl:param name="selection" select="'student[marks > 80]/name'"/>
The transformation can dynamically evaluate it:
<xsl:evaluate xpath="$selection"/>
The dynamically evaluated XPath is:
student[marks > 80]/name
The result will contain:
John
David
The important point is that the XPath expression was not hard-coded directly into the xsl:evaluate instruction. It was supplied dynamically.
The Difference Between Normal XPath and Dynamic XPath
Consider a normal XPath expression:
<xsl:value-of select="student/name"/>
The expression is part of the stylesheet itself.
With dynamic evaluation:
<xsl:variable name="path" select="'student/name'"/>
<xsl:evaluate xpath="$path"/>
the expression is stored as data and then interpreted as XPath.
This distinction is important.
In the first example:
student/name
is XPath syntax in the stylesheet.
In the second example:
student/name
is initially a string value. <xsl:evaluate> converts that string into an executable XPath expression.
Using a Dynamic Expression from XML
A particularly useful application is storing transformation rules in XML.
For example:
<configuration>
<selection>book[@category='programming']</selection>
</configuration>
An XSLT stylesheet could retrieve the selection:
<xsl:variable name="expression" select="configuration/selection"/>
and evaluate it:
<xsl:evaluate xpath="$expression"/>
This allows the transformation logic to be configured through XML rather than changing the stylesheet every time.
The context-item Concept
A dynamically evaluated XPath expression needs a context in which it can be evaluated.
For example:
book/title
does not have the same meaning everywhere. The processor needs to know which node is the starting point.
The context can be supplied using the context-item attribute.
For example:
<xsl:evaluate
xpath="$expression"
context-item="."/>
Here, the current context item is used as the context for the dynamically evaluated expression.
This can be important when the expression refers to relative paths.
Example with a Context Item
Suppose the stylesheet is currently processing:
<department>
<employee>
<name>Robert</name>
</employee>
</department>
The dynamic expression might be:
employee/name
The stylesheet can evaluate it relative to the current department element:
<xsl:evaluate
xpath="'employee/name'"
context-item="."/>
The result is:
Robert
Without an appropriate context item, a relative XPath expression may not produce the expected result.
Dynamic XPath and Variables
<xsl:evaluate> can also work with variables that are made available to the dynamically evaluated expression.
For example, suppose:
<xsl:variable name="minimum" select="50"/>
and the dynamic XPath needs to use this value.
The dynamically evaluated expression could be designed to refer to an external variable, provided that the variable is explicitly made available through the appropriate xsl:evaluate mechanism.
This is useful when both the XPath expression and its input values are determined at runtime.
Dynamic Namespace Handling
Namespaces can make dynamic XPath evaluation more complicated.
Consider XML such as:
<book xmlns="http://example.com/books">
<title>XML Fundamentals</title>
</book>
An XPath expression involving book must use the correct namespace context.
When an XPath expression is dynamically evaluated, the namespace information used by that expression needs to be considered explicitly. XSLT 3.0 provides mechanisms associated with <xsl:evaluate> for supplying namespace bindings when necessary.
This is particularly important when dynamically supplied XPath expressions use prefixes such as:
b:book/b:title
The processor needs to know what the b prefix represents.
Advantages of <xsl:evaluate>
One major advantage is flexibility.
A single stylesheet can support many XPath expressions without having every possible expression hard-coded.
For example, an application could allow a configuration file to specify:
book/title
for one transformation and:
book[price > 100]/title
for another.
The stylesheet itself does not need to be rewritten.
Another advantage is configurable transformation systems. Organizations can maintain transformation rules externally and allow the stylesheet to interpret those rules dynamically.
It can also be useful in generic XML processing applications where the structure or selection criteria vary between transformations.
Limitations and Considerations
Dynamic XPath evaluation should not be used simply because it is available.
A normal XPath expression is generally easier to understand, analyze, optimize, and maintain.
For example, this:
<xsl:value-of select="book/title"/>
is much clearer than constructing the string:
<xsl:variable name="path" select="'book/title'"/>
and then dynamically evaluating it.
Therefore, <xsl:evaluate> is most appropriate when the XPath expression genuinely needs to be determined at runtime.
There can also be performance considerations. A dynamically constructed XPath expression may need to be parsed and compiled during execution. Repeated dynamic evaluation can therefore introduce additional processing overhead compared with a statically known expression.
Security Considerations
Dynamic XPath evaluation should be handled carefully when the expression comes from an untrusted source.
For example, an application should not blindly accept arbitrary XPath expressions from users and execute them without considering what those expressions can access or cause the processor to evaluate.
A safer design is to restrict the expressions that users or external systems are allowed to provide.
For example, instead of accepting any arbitrary XPath expression, an application might permit only a predefined set of expressions or validate the supplied expression before evaluation.
This is particularly important in web applications and systems where transformation rules can be supplied externally.
<xsl:evaluate> vs select
The following uses a static XPath expression:
<xsl:value-of select="book/title"/>
The XPath is known when the stylesheet is compiled.
With dynamic evaluation:
<xsl:variable name="path" select="'book/title'"/>
<xsl:evaluate xpath="$path"/>
the XPath is determined at runtime.
The difference can be summarized as:
| Feature | Normal XPath | <xsl:evaluate> |
|---|---|---|
| Expression known beforehand | Yes | Not necessarily |
| Expression stored as a string | No | Usually |
| Runtime XPath construction | Limited | Yes |
| Easier to optimize | Generally | Potentially more difficult |
| Suitable for configurable rules | Limited | Yes |
| Suitable for fixed selections | Yes | Usually unnecessary |
Practical Applications
Dynamic XPath evaluation can be useful in several situations.
Configurable XML Reports
A reporting system can allow administrators to specify which XML nodes should appear in a report.
For example:
customer/order
could be one selection rule, while another report could use:
customer/order[total > 1000]
The same XSLT stylesheet can process both configurations.
Generic XML Editors
An XML processing application could allow users to specify an XPath expression for finding particular nodes.
The application can pass the expression to the XSLT stylesheet, where <xsl:evaluate> evaluates it.
Rule-Based Transformations
Business rules can sometimes be stored separately from transformation logic.
For example:
<rule>
<expression>product[price > 500]</expression>
</rule>
The stylesheet can retrieve the expression and evaluate it dynamically.
Metadata-Driven Processing
An XML document can contain metadata describing how another XML document should be processed.
Dynamic XPath evaluation allows the transformation to interpret those metadata-driven selections.
Important Difference from String Manipulation
It is important to understand that <xsl:evaluate> does not merely manipulate strings.
For example:
<xsl:value-of select="$expression"/>
would simply output the text contained in $expression.
If $expression contains:
book/title
the result would be the literal text:
book/title
But:
<xsl:evaluate xpath="$expression"/>
treats the value as an XPath expression and evaluates it.
Therefore:
String value
|
v
book/title
|
v
<xsl:evaluate>
|
v
XPath evaluation
|
v
Selected XML nodes
Conclusion
<xsl:evaluate> is an advanced XSLT 3.0 feature that allows XPath expressions to be constructed and evaluated dynamically at runtime. It is particularly useful when the selection or processing logic cannot be determined when the stylesheet is written.
The key distinction is that a normal XPath expression is part of the stylesheet's static logic, whereas <xsl:evaluate> allows an XPath expression represented as data to become executable XPath during the transformation.
It is most valuable for configurable, metadata-driven, and generic XML transformation systems. However, it should be used selectively because static XPath expressions are generally simpler and may offer better performance and maintainability when the required expression is already known.