有没有办法在xslt中对非子元素进行分组?

时间:2016-09-29 17:38:26

标签: xml xslt

我有一个xml文件,它具有以下树结构:

docker-compose up

正如你所看到的,元素foo2不是foo的子元素,但我想 将第一个foo发生的foo2 num =“1”thru num =“4”分组。没有 其中没有一个我可以用作参考......

有没有办法用xsl实现这个目标?

我成功地循环遍历所有foo的出现(使用xsl:for-each属性),但棘手的部分是为每个foo循环包含以下foo2元素。

编辑: 让假装attr有一个随机值,如:

<foo attr1=""/>
<foo2 num="1"/>
<foo2 num="2"/>
<foo2 num="3"/>
<foo2 num="4"/>
<foo attr1=""/>
<foo2 num="1"/>
...

我想要做的是将abc和以下foo组合在一个表中,以便:

<foo attr1="abc"/>
<foo2 num="1"/>
<foo2 num="2"/>
<foo2 num="3"/>
<foo2 num="4"/>
<foo attr1="def"/>
<foo2 num="1"/>

不幸的是它不支持xslt 2.0。

1 个答案:

答案 0 :(得分:1)

这里有两个不同的问题:

  1. 如何使用等效的XSLT 2.0 group-starting-with;

  2. 对节点进行分组
  3. 如何转置(转动)结果,以便您可以构建一个表,其中每个组占用 - 即使构建了一个HTML表 row-by-行

  4. 我建议你分两次通过:

    XSLT 1.0

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:key name="grp" match="foo2" use="generate-id(preceding-sibling::foo[1])" />
    
    <!-- first-pass -->
    <xsl:variable name="groups-rtf">
        <xsl:for-each select="root/foo">
            <group name="{@attr1}">
                <xsl:for-each select="key('grp', generate-id())">
                    <item><xsl:value-of select="@num"/></item>
                </xsl:for-each>
            </group>
        </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="groups" select="exsl:node-set($groups-rtf)/group" />
    
    <xsl:template match="/">
        <table border="1">
            <!-- header row -->
            <tr>
                <xsl:for-each select="$groups">
                    <th><xsl:value-of select="@name"/></th>
                </xsl:for-each>
            </tr>       
            <!-- data rows -->
            <xsl:call-template name="generate-rows"/>
        </table>
    </xsl:template>
    
    <xsl:template name="generate-rows">
        <xsl:param name="i" select="1"/>
        <xsl:if test="$groups/item[$i]">
            <tr>
                <xsl:for-each select="$groups">
                    <td><xsl:value-of select="item[$i]"/></td>
                </xsl:for-each>
            </tr>
            <xsl:call-template name="generate-rows">
                <xsl:with-param name="i" select="$i + 1"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    

    应用于以下示例输入:

    <强> XML

    <root>
        <foo attr1="abc"/>
        <foo2 num="1"/>
        <foo2 num="2"/>
        <foo2 num="3"/>
        <foo2 num="4"/>
        <foo attr1="def"/>
        <foo2 num="5"/>
        <foo2 num="6"/>
    </root>
    

    (渲染)结果将是:

    enter image description here