使用XSL对多个元素进行分组



我有一个类似的XML:

<state>
    <current>block</current>
    <next>air</next>
</state>
<state>
    <current>air</current>
    <next>block</next>
</state>
<state>
    <current>air</current>
    <next>swim</next>
</state>
<state>
    <current>block</current>
    <next>air</next>
</state>

因此,我想将所有"当前"+"下一个"元素分组,以区分我可能遇到的每个当前和下一个元素(使用XSLT1.0)

air
block
swim

我已经使用muenchina方法对"当前"元素或"下一个"元素进行分组,但不能同时对两者进行分组。

我该如何继续?

好吧,事实上它比我预期的要简单。

我只是简单地放了一个:

<xsl:key name="groups" match="//current|//next" use="." />

然后与一起使用

<xsl:template match="current|next" mode="node" >
    <xsl:if test="generate-id() = generate-id(key('groups', normalize-space(.)))">
        <xsl:value-of select="."/>
    </xsl:if>
</xsl:template>

只需应用排序查询并输出唯一的查询:

<xsl:variable name="states">
    <xsl:value-of select="//state/*[contains(name(), 'current next')]/text()"/>
</xsl:variable>
<xsl:for-each select="str:tokenize($states)">
    <xsl:sort select="text()"/>
    <xsl:if test="preceding-sibling::*/text() != text()">
        <xsl:element name="state"><xsl:value-of select="text()"/></xsl:element>
    </xsl:if>
</xsl:for-each>

以下是一个更新,其中包括一个使用exsl节点集的示例,用于不支持标记化的xslt实现:

<xsl:variable name="states">
    <xsl:for-each select="//state/*[contains(name(), 'current next')]">
    <xsl:element name="state">
        <xsl:value-of select="text()"/>
    </xsl:element>
</xsl:variable>
<xsl:for-each select="exsl:node-set($states)/*">
    <xsl:sort select="text()"/>
    <xsl:if test="preceding-sibling::*/text() != text()">
        <xsl:element name="state"><xsl:value-of select="text()"/></xsl:element>
    </xsl:if>
</xsl:for-each>

XSLT是否可以跨多个级别对节点集进行排序也值得一看。我最初预计这不会起作用,但现在不太确定了,因为我想知道libxsl是否会首先压平节点集。如果没有,前面的同级::reference将失败,因为它将只引用直接节点,而不是选择中的一个:

<xsl:for-each select="//state/*[contains(name(), 'current next')]">
    <xsl:sort select="text()"/>
    <xsl:if test="preceding-sibling::*/text() != text()">
        <xsl:element name="state"><xsl:value-of select="text()"/></xsl:element>
    </xsl:if>
</xsl:for-each>

相关内容

  • 没有找到相关文章

最新更新