You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XSTL转带额外标签的XSLT方法及XSLT1.0分组问题求助

XSLT 1.0 实现 Family 节点的父-子分组方案

嘿,刚上手XSLT 1.0碰到这种分组问题很正常,你之前顾虑Muenchian方法要求所有节点子标签一致?其实不用怕——Muenchian分组核心是键值的定义,不是标签的统一性,咱们完全可以针对你的XML结构调整逻辑,同时处理你说的两种情况。

先明确你的核心需求:把那些有的带<Parent>、有的不带的<Family>节点,按父-子关系分组,还要处理重复的父级(比如你输入里重复的General psychiatry),同时不能修改原XML。下面直接上可落地的方案:

完整XSLT代码实现

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <!-- 键1:把每个Family绑定到它的归属父级 -->
    <!-- 有<Parent>就用Parent的值,没有就用自己的Description(作为父级) -->
    <xsl:key name="family-by-parent" match="Family" use="string(Parent | Description[not(../Parent)])"/>

    <!-- 键2:提取所有唯一的父级名称,避免重复输出同一个父级 -->
    <xsl:key name="unique-parents" match="Family" use="string(Parent | Description[not(../Parent)])"/>

    <xsl:template match="/">
        <GroupedFamilies>
            <!-- 遍历所有去重后的父级 -->
            <xsl:for-each select="Family[string(Parent | Description[not(../Parent)])][generate-id() = generate-id(key('unique-parents', string(Parent | Description[not(../Parent)]))[1])]">
                <xsl:variable name="current-parent" select="string(Parent | Description[not(../Parent)])"/>
                <!-- 生成父级节点,带额外标签 -->
                <ParentFamily>
                    <ParentName><xsl:value-of select="$current-parent"/></ParentName>
                    <!-- 生成子级列表:只选有Parent且等于当前父级的Family -->
                    <ChildFamilies>
                        <xsl:for-each select="key('family-by-parent', $current-parent)[Parent]">
                            <ChildFamily>
                                <ChildName><xsl:value-of select="Description"/></ChildName>
                            </ChildFamily>
                        </xsl:for-each>
                    </ChildFamilies>
                </ParentFamily>
            </xsl:for-each>
        </GroupedFamilies>
    </xsl:template>
</xsl:stylesheet>

逻辑拆解,对应你的两种情况

情况1:有明确父-子关系的节点

比如<Family><Description>Liaison Psychiatry</Description><Parent>General psychiatry</Parent></Family>,它会被family-by-parent键绑定到General psychiatry这个父级,在输出时就会出现在General psychiatry的<ChildFamilies>列表里。

情况2:只有父级无对应子级的节点

比如<Family><Description>Old age psychiatry</Description></Family>,因为它没有<Parent>,所以键值就是自己的Description,输出时会作为独立的<ParentFamily>节点,它的<ChildFamilies>会是空的(因为没有节点的<Parent>等于它的名称)。

额外处理:去重重复父级

你输入里有两个<Family><Description>General psychiatry</Description></Family>,通过generate-id() = generate-id(key('unique-parents', ...)[1])这个判断,确保同一个父级只输出一次,不会重复。

输出效果示例

针对你给的输入XML,上面的代码会生成带额外层级标签的XML,结构清晰:

<GroupedFamilies>
    <ParentFamily>
        <ParentName>General psychiatry</ParentName>
        <ChildFamilies>
            <ChildFamily>
                <ChildName>Liaison Psychiatry</ChildName>
            </ChildFamily>
            <ChildFamily>
                <ChildName>Liaison</ChildName>
            </ChildFamily>
        </ChildFamilies>
    </ParentFamily>
    <ParentFamily>
        <ParentName>Old age psychiatry</ParentName>
        <ChildFamilies/>
    </ParentFamily>
</GroupedFamilies>

关于你第一个问题的补充

你提到“如何将XSLT重新转换为添加了额外标签的XSLT?”,如果是指把原XML转换成带父-子嵌套标签的结构化XML(比如上面的输出),那上面的代码就直接实现了这个需求——它以你提供的XML为输入,输出带有<ParentFamily>、<ChildFamily>等额外标签的结果。

如果是想修改你现有生成PDF的XSLT,只需要把这个分组逻辑整合进去就行:比如在输出PDF的章节时,先遍历每个<ParentFamily>,输出父级标题,再遍历对应的<ChildFamily>输出子级内容。


内容的提问来源于stack exchange,提问作者Ranjan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:12:43