在xslt中应用连续转换

时间:2015-01-20 08:00:52

标签: xslt

我是xslt的新手,我有一个变量“name”,它存储转换结果,我们如何使用同一xslt文件中的其他模板转换变量“name”。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
  <xsl:strip-space elements="*" />
    <xsl:template match="@* | node()" >
      <xsl:variable name="name">
          <xsl:copy>
             <xsl:apply-templates select="@* | node()"/>
          </xsl:copy> 
      </xsl:variable>
   </xsl:template>
<xsl:template match="ns1:BP7Locations" >
    <xsl:copy>
      <xsl:apply-templates select="ns1:Entry">
        <xsl:sort select="ns4:Location/ns4:LocationNum" />
      </xsl:apply-templates>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

在XSLT 2.0中,多阶段转换的典型模式是

<xsl:variable name="temp1">
  <xsl:apply-templates mode="phase1"/>
</xsl:variable>
<xsl:variable name="temp2">
  <xsl:apply-templates select="$temp1" mode="phase2"/>
</xsl:variable>
<xsl:apply-templates select="$temp2" mode="phase3"/>

在XSLT 1.0中,这是不允许的,因为该变量包含一个&#34;结果树片段&#34;只能以非常有限的方式处理。几乎每个XSLT 1.0处理器都实现了exslt:node-set()扩展功能,因此您可以绕过此限制。然后代码变为:

<xsl:variable name="temp1">
  <xsl:apply-templates mode="phase1"/>
</xsl:variable>
<xsl:variable name="temp2">
  <xsl:apply-templates select="exslt:node-set($temp1)" mode="phase2"/>
</xsl:variable>
<xsl:apply-templates select="exslt:node-set($temp2)" mode="phase3"/>

您需要将命名空间xmlns:exslt="http://exslt.org/common"添加到样式表中。

您不必为处理的不同阶段使用不同的模式,但它有助于避免难以发现的错误:每个处理阶段的模板规则应该具有相应的模式属性,它也可以最好将每种模式的规则放在一个单独的样式表模块中。

答案 1 :(得分:0)

例如,您可以考虑使用此XML:

<root>
<a>value</a>
</root>

这个XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="root">
    <xsl:variable name="a">
        <xsl:apply-templates select="a" mode="mode1"/>
    </xsl:variable>
    <xsl:apply-templates select="exslt:node-set($a)/a" mode="mode2"/>
</xsl:template>
<xsl:template match="a" mode="mode1">
    <a><xsl:value-of select="'mode1 called'"/></a>
</xsl:template>
<xsl:template match="a" mode="mode2">
    <a><xsl:value-of select="concat(., ' mode2 called')"/></a>
</xsl:template>
</xsl:stylesheet>

这将产生以下输出:

<?xml version="1.0" encoding="utf-8"?>
<a xmlns:exslt="http://exslt.org/common">mode1 called mode2 called</a>

XSLT的第一个模板有一个变量a,它在处理元素<a>之后存储数据,然后xsl:apply-templates处理变量a中的数据再次。这里@mode xsl:template区分了第二个和第三个模板。