xslt:在select和match中使用变量

时间:2016-12-14 06:53:59

标签: html xslt

我需要指定从html文件到文本文件的输出顺序。因此我使用xsl:apply-templates选择方法。 它工作正常,但为了微调不同节点的输出,我需要一个相应的模板,而不仅仅是一般模板。这也行,但我需要在模板的匹配模式中重复选择模式。

我喜欢定义一个包含模式的变量,因此只需要定义一次。 下面是我的简化样式表和简化的html,它不起作用,但给出了我想要完成的内容。 是否可以使用这样的变量?如果需要,我可以同时使用xslt 1.0和2.0。

<xsl:stylesheet ...>
    ...

  <xsl:variable name="first">div[@class='one']</xsl:variable>
  <xsl:variable name="second">div[@class='two']</xsl:variable>

  <xsl:template match="/*">
    <xsl:apply-templates select="//$first"/>                                        
    <xsl:apply-templates select="//$second"/>                                       
    ...
  </xsl:template>

  <xsl:template match="//$first">
    <xsl:text>Custom text for class one:</xsl:text><xsl:value-of select="text()"/>
  </xsl:template>

  <xsl:template match="//$second">
    <xsl:text>Custom text for class two:</xsl:text><xsl:value-of select="text()"/>
  </xsl:template>

</xsl:stylesheet>   

html:

...
<div class="two">text from two</div>
<div class="one">text from one </div>
...

期望的输出:

Custom text for class one: text from one
Custom text for class two: text from two

2 个答案:

答案 0 :(得分:0)

在XSLT 1或2中无法使用类似的变量。唯一的方法是编写一个样式表来生成第二个样式表并单独执行。

在XSLT 3中,有一些名为static variables/parametersshadow attributes的新功能可以提供帮助,或者您可以使用transform函数直接使用XSLT执行新生成的样式表,而不是在与宿主语言分开的步骤。

但是使用XSLT 2可以缩短

<xsl:apply-templates select="//div[@class='one']"/>                                        
<xsl:apply-templates select="//div[@class='two']"/> 

<xsl:apply-templates select="//div[@class='one'], //div[@class='two']"/>

为了完整起见,这里是XSLT 3方法,在阴影属性中使用了两个静态参数:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:param name="first" static="yes" as="xs:string" select="&quot;div[@class='one']&quot;"/>

    <xsl:param name="second" static="yes" as="xs:string" select="&quot;div[@class='two']&quot;"/>

    <xsl:template match="/*">
        <xsl:apply-templates _select="//{$first}, //{$second}"/>                                        
    </xsl:template>

    <xsl:template _match="{$first}">
        <xsl:text>Custom text for class one:</xsl:text><xsl:value-of select="text()"/>
    </xsl:template>

    <xsl:template _match="{$second}">
        <xsl:text>Custom text for class two:</xsl:text><xsl:value-of select="text()"/>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

XSLT中的变量保存值,而不是表达式的片段。 (换句话说,XSLT不是一种宏语言)。

作为需要XSLT 3.0的Martin解决方案的替代方案,您可以考虑使用有时称为“元样式表”的方法 - 将转换作为样式表本身的预处理步骤。您甚至可以编写通用样式表以使用带有阴影属性(如_match)的XSLT 3.0语法,并执行XSLT预处理阶段以将其转换为常规XSLT 1.0或2.0语法以供执行。