XSLT条件判断失效:如何基于子节点规则控制ApacheFOP不生成文档?
问题描述
使用ApacheFOP生成AFP和PDF时,需要实现以下判断逻辑:当存在<attribute>节点满足name='NUMMER'且value!='0'时,不生成任何文档。
现有XML结构如下:
<Data> <product> <attribute> <name>NUMMER</name> <actionType>RM</actionType> <actionReason>DISCN</actionReason> <value>0</value> </attribute> <attribute> <name>NUMMER</name> <actionType>RM</actionType> <actionReason>DISCN</actionReason> <value>12345</value> </attribute> <attribute> <name>RETURN</name> <actionType>RM</actionType> <actionReason>DISCN</actionReason> <value>00</value> <valueDescription>NO</valueDescription> </attribute> <attribute> <name>ADRESS</name> <actionType>RM</actionType> <actionReason>DISCN</actionReason> <value>4</value> <valueDescription>ABC</valueDescription> </attribute> </product> </Data>
尝试过以下几种写法均未生效:
<xsl:when test="Data/product/attribute[name='NUMMER' and value!='0']"></xsl:when> <xsl:when test="Data/product/attribute[name='NUMMER' and not(value='0')]"></xsl:when>
实际使用的代码如下,但始终未进入<xsl:when>分支,反而生成了不需要的文档:
<xsl:when test="Data/product/attribute[name='NUMMER' and value!=0]"> <!-- No details to print --> </xsl:when> <xsl:otherwise> <!--Here i have a logic to call the main template which will produce the document for me--> </xsl:otherwise>
解决方案
核心问题分析
- XPath路径上下文错误:你的XPath使用了相对路径
Data/product/attribute,但如果当前执行<xsl:when>的节点不是XML的根节点(比如当前在product节点下),这个路径就会找不到对应节点,导致条件不成立。 - 类型比较问题:
value!=0是将字符串类型的value节点值转换为数字后比较,虽然大部分时候能工作,但如果value是带前导零的字符串可能出现意外,更稳妥的是用字符串比较value!='0'。
修正后的代码
方法1:使用绝对路径(推荐)
在XPath前加上/,确保从根节点开始查找:
<xsl:when test="/Data/product/attribute[name='NUMMER' and value!='0']"> <!-- No details to print --> </xsl:when> <xsl:otherwise> <!-- 调用生成文档的主模板逻辑 --> </xsl:otherwise>
方法2:匹配当前节点的相对路径
如果当前执行逻辑的节点是Data或product,调整路径为相对路径:
- 若当前节点是
Data:
<xsl:when test="product/attribute[name='NUMMER' and value!='0']"> <!-- No details to print --> </xsl:when>
- 若当前节点是
product:
<xsl:when test="attribute[name='NUMMER' and value!='0']"> <!-- No details to print --> </xsl:when>
方法3:用exists()明确判断节点存在性(可选)
用exists()函数更清晰地表达判断逻辑,避免空节点集合的隐式转换问题:
<xsl:when test="exists(/Data/product/attribute[name='NUMMER' and value!='0'])"> <!-- No details to print --> </xsl:when>
内容的提问来源于stack exchange,提问作者Pooja
相关产品推荐
相关产品推荐

