XSLT 3.0累加器未更新为空值的问题咨询
问题:如何让XSLT累加器处理空Tag2节点的情况?
输入XML
<?xml version="1.0" encoding="UTF-8"?> <Root> <Entry> <Tag1>A1</Tag1> <Tag2>B1</Tag2> </Entry> <Entry> <Tag1>A2</Tag1> <Tag2/> </Entry> </Root>
现有XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0"> <xsl:output method="text"/> <xsl:mode on-no-match="shallow-skip" streamable="yes" use-accumulators="#all"/> <xsl:accumulator name="Tag2" as="xs:string" initial-value="''" streamable="yes"> <xsl:accumulator-rule match="Tag2/text()" select="." /> </xsl:accumulator> <xsl:template match="/*" expand-text="yes"> <xsl:apply-templates/> Tag2 {accumulator-after('Tag2')} </xsl:template> </xsl:stylesheet>
当前输出
Tag2 B1
期望输出
Tag2 <<empty>>
解决方案
原累加器仅匹配Tag2/text()节点,空的Tag2没有文本节点,因此不会触发累加器更新,导致其值始终保留第一个Tag2的内容。要处理空节点,需要修改累加器的匹配规则,直接匹配Tag2元素本身,并判断其是否包含文本内容:
修改后的累加器代码如下:
<xsl:accumulator name="Tag2" as="xs:string" initial-value="''" streamable="yes"> <xsl:accumulator-rule match="Tag2" select="if (text()) then text() else '<<empty>>'" /> </xsl:accumulator>
说明
- 现在累加器会在遇到每个
Tag2元素时更新值:如果元素有文本内容,就取文本;如果是空元素(无文本节点),则将累加器值设为<<empty>>。 - 第二个
Entry中的空Tag2会触发这条规则,将累加器的值覆盖为期望的<<empty>>,最终输出符合需求。
内容的提问来源于stack exchange,提问作者aj2288
相关产品推荐
相关产品推荐

