XSLT中如何准确引用其他节点计算值而非重复公式
问题描述
当前XSLT处理后,<FRP_2><MAIN>下的<R0040C0040>输出NaN,原因是它要引用的<FRP_1><MAIN>下的<R0030C0010>是通过XSLT动态计算生成的节点,而非原始XML自带的。要求不能直接复制format-number($R0020C0030 + $R0030C0030, '0.00')这个计算公式,要准确引用该计算后的值。
问题根源
原代码里FRP_2模板用document('')//FRP_1/MAIN/R0030C0010是去读取XSLT样式表本身的内容,而不是处理后生成的<FRP_1>节点。因为<R0030C0010>是处理<FRP_1>时才生成的,样式表里本来没有这个节点,所以number()转换后得到NaN。
解决方案
核心思路是先完成<FRP_1>的处理并保存结果,再在<FRP_2>的处理中使用这个已处理好的结果。下面是具体实现:
修改后的XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 根模板:先处理FRP_1并保存结果,再处理FRP_2 --> <xsl:template match="/FRP_S"> <FRP_S> <!-- 处理FRP_1,把结果存入变量 --> <xsl:variable name="processedFRP1"> <xsl:apply-templates select="FRP_1"/> </xsl:variable> <!-- 输出处理好的FRP_1 --> <xsl:copy-of select="$processedFRP1"/> <!-- 处理FRP_2时传入FRP_1的处理结果 --> <xsl:apply-templates select="FRP_2"> <xsl:with-param name="frp1Data" select="$processedFRP1"/> </xsl:apply-templates> </FRP_S> </xsl:template> <xsl:template match="FRP_1"> <xsl:copy> <MAIN> <xsl:copy-of select="MAIN/*"/> <xsl:variable name="R0020C0030" select="MAIN/R0020C0030/text()"/> <xsl:variable name="R0030C0030" select="MAIN/R0030C0030/text()"/> <xsl:variable name="R0030C0010" select="format-number($R0020C0030 + $R0030C0030, '0.00')"/> <R0030C0010> <xsl:value-of select="$R0030C0010"/> </R0030C0010> </MAIN> </xsl:copy> </xsl:template> <xsl:template match="FRP_2"> <xsl:param name="frp1Data"/> <xsl:copy> <MAIN> <xsl:copy-of select="MAIN/*"/> <!-- 从预存的FRP_1处理结果中取R0030C0010的值 --> <xsl:variable name="targetValue" select="$frp1Data/FRP_1/MAIN/R0030C0010/text()"/> <R0040C0040> <xsl:value-of select="format-number(number($targetValue), '0.00')"/> </R0040C0040> </MAIN> </xsl:copy> </xsl:template> </xsl:stylesheet>
XML输入文件
<?xml version="1.0" encoding="UTF-8"?> <FRP_S> <FRP_1> <MAIN> <R0010C0030>10</R0010C0030> <R0020C0030>20</R0020C0030> <R0030C0030>30</R0030C0030> </MAIN> </FRP_1> <FRP_2> <MAIN> <R0010C0010>6</R0010C0010> </MAIN> </FRP_2> </FRP_S>
最终输出结果
<?xml version="1.0" encoding="UTF-8"?> <FRP_S> <FRP_1> <MAIN> <R0010C0030>10</R0010C0030> <R0020C0030>20</R0020C0030> <R0030C0030>30</R0030C0030> <R0030C0010>50</R0030C0010> </MAIN> </FRP_1> <FRP_2> <MAIN> <R0010C0010>6</R0010C0010> <R0040C0040>50</R0040C0040> </MAIN> </FRP_2> </FRP_S>
内容的提问来源于stack exchange,提问作者Jian
相关产品推荐
相关产品推荐

