如何在XSL / XPath中按部分名称选择元素?

时间:2012-02-13 20:01:04

标签: xml regex xslt transform

如何使用apply-templates仅按名称(而不是值)选择以特定模式结尾的元素?假设以下xml ...

<report>
  <report_item>
    <report_created_on/>
    <report_cross_ref/>
    <monthly_adj/>
    <quarterly_adj/>
    <ytd_adj/>
  </report_item>
  <report_item>
   ....
  </report_item>
</report>

我想在<xsl:apply-templates>的所有实例上使用<report_item>,其中后代元素以'adj`结尾,因此,在这种情况下,只选择monthly_adj,quaterly_adj和ytd_adj并应用于模板。

<xsl:template match="report">
   <xsl:apply-templates select="report_item/(elements ending with 'adj')"/>
</xsl:template>

2 个答案:

答案 0 :(得分:10)

我不认为正则表达式语法在此上下文中可用,即使在XSLT 2.0中也是如此。但在这种情况下你不需要它。

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

*匹配任何节点

[pred]对选择器执行节点测试(在本例中为*)(其中pred是在所选节点的上下文中评估的谓词)

name()会返回元素的标记名称(为此目的,应该等同于local-name)。

ends-with()是一个内置的XPath字符串函数。

答案 1 :(得分:2)

稍微整洁的解决方案(仅限XSLT 2.0+):

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

这是一个自我测试,以证明它的工作原理。 (经过撒克逊测试)。

<?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>