在xsl:for-each-group中使用XPath筛选current-group()子集的问题
为什么
current-group()/foo无结果,但复制到变量后$foo/foo生效? 这个问题的核心差异在于current-group()返回的内容和你存入变量$foo的内容在XPath中的处理逻辑完全不同:
1. current-group()的本质:节点序列
current-group()是XSLT分组函数,它返回的是当前组内所有节点的序列——这些节点并没有脱离原来的源文档树,仍然保留着它们原本的层级关系和上下文。
如果你写current-group()/foo,这个表达式的语义是:
遍历序列中的每一个节点,选取该节点的直接子节点
foo
如果你的组本身就是由foo节点组成的(或者组内节点的直接子节点不是foo),那这个表达式自然返回空结果——因为你在找每个组节点的子节点foo,而不是组内的foo节点本身。
2. 变量$foo的本质:临时文档片段
当你用<xsl:copy-of select="current-group()"/>把组内节点复制到变量时,XSLT会创建一个临时的文档片段节点,并把组内所有节点作为这个文档片段的直接子节点。
这时候$foo/foo的语义是:
选取临时文档片段节点下的所有直接子节点
foo
如果你的组原本就包含foo节点,那这些节点现在是文档片段的直接子节点,自然能被$foo/foo匹配到。
正确的写法(无需复制到变量)
如果你想直接从current-group()中筛选出目标节点,不需要借助变量,直接用以下对应写法即可:
- 如果要筛选组内本身就是
foo的节点:current-group()[self::foo] - 如果要筛选组内节点下的所有
foo节点(包括深层级):current-group()//foo - 如果要筛选组内节点的直接
foo子节点:current-group()/foo
(这个就是你最初的写法,但只有当组内节点是foo的父节点时才会生效)
内容的提问来源于stack exchange,提问作者Hans Hübner
相关产品推荐
相关产品推荐

