XSLT 2.0 for-each-group分组异常:无法获取深层节点
XSLT 2.0 多文档分组无法获取深层节点的问题解决
问题原因
你遇到的核心问题通常是以下两种情况:
- 分组时仅以
group节点作为分组键,但后续没有正确导航到其下的domain_section、skill等子节点,导致上下文丢失 - 多文档合并过程中,没有正确获取所有目标文档的完整节点树,只抽取了
group节点而忽略了其子节点层级
正确分组实现步骤
假设你的源XML结构类似这样(示例):
<!-- 文档1.xml --> <root> <group name="前端开发"> <domain_section name="HTML/CSS"> <skill name="Flexbox"/> <skill name="Grid"/> </domain_section> </group> </root> <!-- 文档2.xml --> <root> <group name="前端开发"> <domain_section name="JavaScript"> <skill name="ES6+"/> <skill name="React"/> </domain_section> </group> <group name="后端开发"> <domain_section name="Node.js"> <skill name="Express"/> </domain_section> </group> </root>
1. 合并多文档节点
先通过document()函数加载所有目标文档,获取所有group节点:
<xsl:variable name="all-groups" select="document(('文档1.xml', '文档2.xml'))//group"/>
2. 按group的name属性分组
使用xsl:for-each-group按分组键分组,同时保留完整节点树:
<xsl:template match="/"> <!-- 合并所有文档的group节点 --> <xsl:variable name="all-groups" select="document(('文档1.xml', '文档2.xml'))//group"/> <!-- 按group的name属性分组 --> <xsl:for-each-group select="$all-groups" group-by="@name"> <!-- 输出分组名称 --> <h2><xsl:value-of select="current-grouping-key()"/></h2> <!-- 遍历分组内所有group节点下的domain_section --> <xsl:for-each select="current-group()/domain_section"> <h3><xsl:value-of select="@name"/></h3> <!-- 遍历skill节点 --> <ul> <xsl:for-each select="skill"> <li><xsl:value-of select="@name"/></li> </xsl:for-each> </ul> </xsl:for-each> </xsl:for-each-group> </xsl:template>
3. 生成结构化变量(可选)
如果需要将分组结果存储为结构化变量供后续构建表格使用,可以用xsl:variable结合节点集:
<xsl:variable name="grouped-data"> <xsl:for-each-group select="$all-groups" group-by="@name"> <group category="{current-grouping-key()}"> <xsl:copy-of select="current-group()/domain_section"/> </group> </xsl:for-each-group> </xsl:variable> <!-- 后续可以用$grouped-data构建表格 --> <xsl:template match="group" mode="build-table"> <tr> <td><xsl:value-of select="@category"/></td> <td> <xsl:for-each select="domain_section"> <div><xsl:value-of select="@name"/>:<xsl:value-of select="skill/@name" separator=", "/></div> </xsl:for-each> </td> </tr> </xsl:template>
关键注意点
- 确保
document()函数的路径正确,若文档在同一目录下直接写文件名即可 - 使用
current-group()访问分组内的所有节点,而非仅当前节点,这样能获取所有同组的深层子节点 - 分组键要选择唯一标识分组的属性/节点值,比如
@name,避免分组混乱
内容的提问来源于stack exchange,提问作者Roman G
相关产品推荐
相关产品推荐

