如何通过XSLT根据XML节点值设置Expression节点指定文本?
解决XSLT处理XML时Expression节点为空的问题
需求:当XML中的<Valid_Amount>节点包含数据时,<Expression>节点返回文本"WELCOME";当<Invalid_Amount>节点包含数据时,<Expression>节点返回文本"THANKS"。当前输出的<Expression>节点为空,需修正。
XML源数据
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TRY%20v1.xsd"> <row> <Invalid_Amount>155.2</Invalid_Amount> <Valid_Amount></Valid_Amount> <Trustee_Name>Bruce Wayne</Beneficiary_Name> </row> <row> <Invalid_Amount></Invalid_Amount> <Valid_Amount>9880</Valid_Amount> <Trustee_Name>Clark Kent</Trustee_Name> </row> <row> <Invalid_Amount>1665.2</Invalid_Amount> <Valid_Amount></Valid_Amount> <Trustee_Name>Diana Prince</Trustee_Name> </row> </root>
当前输出结果
<Codac> <Payment> <Name>Bruce Wayne</Name> <Expression></Expression> </Payment> <Payment> <Name>Clark Kent</Name> <Expression></Expression> </Payment> <Payment> <Name>Diana Prince</Name> <Expression></Expression> </Payment> </Codac>
期望输出结果
<Codac> <Payment> <Name>Bruce Wayne</Name> <Expression>THANKS</Expression> </Payment> <Payment> <Name>Clark Kent</Name> <Expression>WELCOME</Expression> </Payment> <Payment> <Name>Diana Prince</Name> <Expression>THANKS</Expression> </Payment> </Codac>
当前XSLT代码
<?xml version='1.0' ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <Codac> <xsl:for-each select="root/row"> <Payment> <Name> <xsl:value-of select="Trustee_Name"/> </Name> <Expression> <xsl:call-template name="NotEmpty"> </xsl:call-template> </Expression> </Payment> </xsl:for-each> </Codac> </xsl:template> <xsl:template name="NotEmpty"> <xsl:param name="S" select="Invalid_Amount != ''"/> <xsl:param name="T" select="Valid_Amount != ''"/> <xsl:for-each select="../row"> <xsl:choose> <xsl:when test="Invalid_Amount =''"> <xsl:value-of select="THANKS"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="WELCOME"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> </xsl:template> </xsl:stylesheet>
问题分析
- 上下文错误:
NotEmpty模板内使用<xsl:for-each select="../row">,会重新遍历所有<row>节点,而非当前处理的单个row,导致逻辑混乱。 - 字符串输出错误:
<xsl:value-of select="THANKS"/>是尝试选择名为THANKS的节点,而非输出字符串,找不到对应节点时就会输出空值。 - 判断逻辑颠倒:当前代码在
Invalid_Amount为空时输出THANKS,与需求相反;且未优先判断Valid_Amount的情况。 - 冗余参数:定义的参数
S和T未实际使用,属于多余代码。
修正后的XSLT代码
<?xml version='1.0' ?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <Codac> <xsl:for-each select="root/row"> <Payment> <Name> <xsl:value-of select="Trustee_Name"/> </Name> <Expression> <xsl:choose> <xsl:when test="Valid_Amount != ''"> <xsl:text>WELCOME</xsl:text> </xsl:when> <xsl:when test="Invalid_Amount != ''"> <xsl:text>THANKS</xsl:text> </xsl:when> </xsl:choose> </Expression> </Payment> </xsl:for-each> </Codac> </xsl:template> </xsl:stylesheet>
修正说明
- 移除了冗余的
NotEmpty模板,直接在当前<row>上下文内处理判断逻辑,避免上下文切换错误。 - 使用
<xsl:text>输出固定字符串,确保正确输出目标文本而非尝试选择节点。 - 调整判断顺序:先检查
Valid_Amount是否非空,符合需求优先级;再检查Invalid_Amount非空的情况。 - 简化代码结构,提升可读性。
内容的提问来源于stack exchange,提问作者OyeRep
相关产品推荐
相关产品推荐

