简体   繁体   English

XSLT 在不改变顺序的情况下分组/合并节点

[英]XSLT Grouping/merging nodes without changing the order

I found a lot of grouping questions and they almost got me the wanted result.我发现了很多分组问题,它们几乎让我得到了想要的结果。 However, with these it was usually the case that the nodes to be grouped were already listed under a separate group node, so that the apply-templates could target exactly this parent node.然而,对于这些,通常情况下要分组的节点已经列在单独的组节点下,因此应用模板可以准确地针对该父节点。 I have the following Input XML:我有以下输入 XML:

<ROOT>
    <ARTICLE>
        <IMAGE name="demo.jpg" />
        <TABLE>
            <TABLETHEAD>
                Name1
            </TABLETHEAD>
            <TABLEROW>
                <TABLETH>
                    Some Text
                </TABLETH>
                <TABLETD>
                    Some more Text
                </TABLETD>
            </TABLEROW>
        </TABLE>
        <TABLE>
            <TABLETHEAD>
                Name1
            </TABLETHEAD>
            <TABLEROW>
                <TABLETH>
                    Demo Text
                </TABLETH>
                <TABLETD>
                    More Demo Text
                </TABLETD>
            </TABLEROW>
            <TABLEROW>
                <TABLETH>
                    Even more Text
                </TABLETH>
                <TABLETD>
                    Text
                </TABLETD>
            </TABLEROW>
        </TABLE>
        <GRAPHIC name="demo-graphic.eps" />
    </ARTICLE>
</ROOT>

And this is the desired output:这是所需的 output:

<ROOT>
    <ARTICLE>
        <IMAGE name="demo.jpg" />
        <TABLE>
            <TABLETHEAD>
                Name1
            </TABLETHEAD>
            <TABLEROW>
                <TABLETH>
                    Some Text
                </TABLETH>
                <TABLETD>
                    Some more Text
                </TABLETD>
            </TABLEROW>
            <TABLEROW>
                <TABLETH>
                    Demo Text
                </TABLETH>
                <TABLETD>
                    More Demo Text
                </TABLETD>
            </TABLEROW>
            <TABLEROW>
                <TABLETH>
                    Even more Text
                </TABLETH>
                <TABLETD>
                    Text
                </TABLETD>
            </TABLEROW>
        </TABLE>
        <GRAPHIC name="demo-graphic.eps" />
    </ARTICLE>
</ROOT>

The tables should be grouped by the same text in TABLETHEAD and the TABLEROWs should be added in each case, so that for each different TABLETHEAD text there is a single table with the TABLEROWs of all the tables belonging to the group.这些表应按 TABLETHEAD 中的相同文本分组,并且应在每种情况下添加 TABLEROW,以便对于每个不同的 TABLETHEAD 文本,都有一个表,其中包含属于该组的所有表的 TABLEROW。

The important thing is that the sibling nodes (eg IMG, GRAPHIC, and many more) remain and the whole order does not change.重要的是兄弟节点(例如 IMG、GRAPHIC 等)保持不变,并且整个顺序不会改变。 This is exactly my problem:这正是我的问题:

If my TABLEs were listed under a common parent node eg "TABLES", I could get on with a simple grouping similar to Applying Muenchian grouping for a simple XML with XSLT .如果我的 TABLE 列在公共父节点(例如“TABLES”)下,我可以继续进行类似于将 Muenchian 分组应用于简单的 XML 和 XSLT 的简单分组 So I either lose the sibling nodes or change the order.所以我要么丢失兄弟节点,要么改变顺序。

I am using xslt 2.0.我正在使用 xslt 2.0。

With the help of Martin's comment (thanks a lot:) I came up with combining group-by and group-adjacent:在 Martin 的评论(非常感谢:)的帮助下,我想到了将 group-by 和 group-adjacent 结合起来:

<xsl:template match="ARTICLE">
    <xsl:copy>
        <xsl:apply-templates select="@*" />
        <xsl:for-each-group select="node()" group-adjacent="string(self::TABLE/TABLETHEAD)">
            <xsl:for-each-group select="current-group()" group-by="string(self::TABLE/TABLETHEAD)">
                <xsl:choose>
                    <xsl:when test="self::TABLE">
                        <TABLE>
                            <xsl:apply-templates select="current-group()[1]/@* | current-group()[1]/TABLETHEAD[1] | current-group()/TABLEROW" />
                        </TABLE>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()" />
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

This worked for me.这对我有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM