将 XSLT 转换应用于已转换的 XML [英] Apply XSLT Transform to an already transformed XML
问题描述
全部,
我有一个 XML 文件,我使用 XSLT 文档将其转换为另一个 XML.
I have an XML file which I transform it using an XSLT document to another XML.
我能否在同一个 XSLT 文件中定义另一组转换以应用于第一个转换的结果 XML?
Can I define another set of transformations in the same XSLT file to be applied in the result XML of the first transformation?
谢谢,
MK
推荐答案
是.
我.这个 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>
请注意:
实际上执行了两个转换,第二个是对第一个的结果执行的.
Two transformations are actually performed, the second is performed on the result of the first.
第一次转换的结果是变量$vrtfPass1
的内容.
The result of the first transformation is the content of the variable $vrtfPass1
.
在 XSLT 1.0 中,包含动态生成(临时)XML 树(XML 文档或 XML 片段)的变量类型是 RTF(结果树片段).RTF 上不可能进行 XPath 操作——它需要使用扩展函数 xxx:node-set()
转换为常规节点集,该函数由绝大多数 XSLT 1.0 提供处理器供应商.在这个例子中使用了 exslt:node-set(),因为 EXSLT 是由许多不同的供应商实现的.
In XSLT 1.0 the type of variables that contain dynamically generated (temporary) XML trees (XML document or XML fragment) is RTF (Result-Tree-Fragment). No XPath operations are possible on an RTF -- it needs to be converted to a regular node-set using the extension function xxx:node-set()
, which is provided by the vast majority of XSLT 1.0 processor vendors. In this example exslt:node-set() is used, because EXSLT is implemented by many different vendors.
第二个转换应用于第一个的结果:<xsl:apply-templates select="ext:node-set($vrtfPass1)/*"mode="pass2"/>
.使用单独的 mode
以干净地分离两个转换的代码.
The second transformation is applied on the result of the first: <xsl:apply-templates select="ext:node-set($vrtfPass1)/*" mode="pass2"/>
. A separate mode
is used in order to cleanly separate the code of the two transformations.
第一个转换将每个 num/text()
乘以 2.第二个转换将每个 num/text()
增加.结果是 2*.+1
The first transformation multiplies each num/text()
by 2. The second transformation increments each num/text()
. The result is 2*.+1
二.这个 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()
扩展函数.
Do note: In XSLT 2.0/XPath 2.0 the RTF type has been abolished. No xxx:node-set()
extension function is needed.
这篇关于将 XSLT 转换应用于已转换的 XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!