全部,
我有一个XML文件,我使用XSLT文档将其转换为另一个XML。
我可以在同一个XSLT文件中定义另一组转换,以便在第一次转换的结果XML中应用吗?
谢谢,
MK
答案 0 :(得分:9)
是
<强>予。这个XSLT 1.0转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfPass1">
<xsl:apply-templates/>
</xsl:variable>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num/text()">
<xsl:value-of select="2*."/>
</xsl:template>
<xsl:template match="num/text()" mode="pass2">
<xsl:value-of select="1+."/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时:
<t>
<num>1</num>
<num>2</num>
<num>3</num>
<num>4</num>
<num>5</num>
</t>
<强>产生强>:
<t>
<num>3</num>
<num>5</num>
<num>7</num>
<num>9</num>
<num>11</num>
</t>
请注意:
实际执行了两次转换,第二次是对第一次转化的结果执行。
第一次转化的结果是变量$vrtfPass1
的内容。
在XSLT 1.0中,包含动态生成(临时)XML树(XML文档或XML片段)的变量类型是RTF (结果树片段)。 RTF上无法进行XPath操作 - 需要使用扩展函数xxx:node-set()
将其转换为常规节点集,扩展函数由绝大多数XSLT 1.0处理器供应商提供。在此示例中,使用了exslt:node-set(),因为EXSLT由许多不同的供应商实现。
第二个转换适用于第一个的结果:<xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
。使用单独的mode
来彻底分离两个转换的代码。
第一次转换将每个num/text()
乘以2.第二次转换会增加每个num/text()
。结果是2*.+1
<强> II。这个XSLT 2.0转换:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vPass1">
<xsl:apply-templates mode="pass1"/>
</xsl:variable>
<xsl:template match="node()|@*" mode="pass1">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass1"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="pass2">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="pass2"/>
</xsl:copy>
</xsl:template>
<xsl:template match="num/text()" mode="pass1">
<xsl:value-of select="2*xs:integer(.)"/>
</xsl:template>
<xsl:template match="num/text()" mode="pass2">
<xsl:value-of select="1+."/>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$vPass1" mode="pass2"/>
</xsl:template>
</xsl:stylesheet>
应用于同一XML文档时,会生成相同的想要和正确的结果。
请注意:在XSLT 2.0 / XPath 2.0中,RTF类型已被废除。不需要xxx:node-set()
扩展功能。