How do I use apply-templates to select only those elements by name (not value) that end with a specific pattern? Assume the following xml...
<report>
<report_item>
<report_created_on/>
<report_cross_ref/>
<monthly_adj/>
<quarterly_adj/>
<ytd_adj/>
</report_item>
<report_item>
....
</report_item>
</report>
I want to use <xsl:apply-templates>
on all instances of <report_item>
where descendant elements end with 'adj`, so, in this case, only monthly_adj, quaterly_adj, and ytd_adj would be selected and applied with the template.
<xsl:template match="report">
<xsl:apply-templates select="report_item/(elements ending with 'adj')"/>
</xsl:template>
The XPath expression @* | node() selects the union, sorted in document order, of (attribute nodes of the context item and XML child nodes of the context item in sense of the XDM).
The XSLT <xsl:value-of> element is used to extract the value of selected node. It puts the value of selected node as per XPath expression, as text.
XPath is a major element in the XSLT standard. XPath can be used to navigate through elements and attributes in an XML document.
I don't think that regular expression syntax is available in this context, even in XSLT 2.0. But you don't need it in this case.
<xsl:apply-templates select="report_item/*[ends-with(name(), 'adj')]"/>
*
matches any node
[pred]
performs a node test against the selector (in this case *
) (where pred
is a predicate evaluated in the context of the selected node)
name()
returns the element's tag name (should be equivalent to local-name
for this purpose).
ends-with()
is a built-in XPath string function.
Slightly neater solution (XSLT 2.0+ only):
<xsl:apply-templates select="report_item/*[matches(name(),'adj$')]"/>
Here is a self-test to prove it works. (Tested on Saxon).
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs fn">
<xsl:output method="xml" indent="yes" encoding="utf-8" />
<xsl:variable name="report-data">
<report>
<report_item>
<report_created_on/>
<report_cross_ref/>
<monthly_adj>Jan</monthly_adj>
<quarterly_adj>Q1</quarterly_adj>
<ytd_adj>2012</ytd_adj>
</report_item>
</report>
</xsl:variable>
<xsl:template match="/" name="main">
<reports-ending-with-adj>
<xsl:element name="using-regex">
<xsl:apply-templates select="$report-data//report_item/*[fn:matches(name(),'adj$')]"/>
</xsl:element>
<xsl:element name="using-ends-with-function">
<xsl:apply-templates select="$report-data//report_item/*[fn:ends-with(name(), 'adj')]"/>
</xsl:element>
</reports-ending-with-adj>
</xsl:template>
</xsl:stylesheet>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With