How to select elements according to their name in XSL / XPath?

How to use a template to select only those elements by name (not value) that end with a specific template? 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> for all instances of <report_item> where the descendant elements end with "adj", so in this case only the template with the parameters month_adj, quaterly_adj and ytd_adj will be selected and applied.

 <xsl:template match="report"> <xsl:apply-templates select="report_item/(elements ending with 'adj')"/> </xsl:template> 
+6
source share
2 answers

I do not think that regular expression syntax is available in this context, even in XSLT 2.0. But you do not need it in this case.

 <xsl:apply-templates select="report_item/*[ends-with(name(), 'adj')]"/> 

* matches any node

[pred] performs a node test against a selector (in this case * ) (where pred is a predicate evaluated in the context of the selected node)

name() returns the name of the element tag (for this purpose it should be equivalent to local-name ).

ends-with() is a built-in XPath string function.

+10
source

Weaker solution (only for XSLT 2.0+):

 <xsl:apply-templates select="report_item/*[matches(name(),'adj$')]"/> 

Here is a self test to prove that 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> 
+2
source

Source: https://habr.com/ru/post/908367/


All Articles