在 xslt 中应用连续转换
Applying consecutive transformations in 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>
举个例子,你可以考虑这个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
中的数据。这里 xsl:template
上的 @mode
区分第二个和第三个模板。
在 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 中这是不允许的,因为该变量包含一个 "result tree fragment",它只能以非常有限的方式进行处理。几乎每个 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"
添加到您的样式表。
你不必针对不同的处理阶段使用不同的模式,但它有助于避免难以发现的错误:每个处理阶段的模板规则应该有相应的模式属性,它也可以将每种模式的规则放在单独的样式表模块中是个好主意。
我是 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>
举个例子,你可以考虑这个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
中的数据。这里 xsl:template
上的 @mode
区分第二个和第三个模板。
在 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 中这是不允许的,因为该变量包含一个 "result tree fragment",它只能以非常有限的方式进行处理。几乎每个 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"
添加到您的样式表。
你不必针对不同的处理阶段使用不同的模式,但它有助于避免难以发现的错误:每个处理阶段的模板规则应该有相应的模式属性,它也可以将每种模式的规则放在单独的样式表模块中是个好主意。