如何在 XSLT 转换中对结果进行排序?

How to sort results inside XSLT tranformation?

https://xsltfiddle.liberty-development.net/jz1PuPb

是否可以在将结果写入输出流之前对 xslt 转换中的结果进行排序?

我的目标是 1) 将以下 xml 转换为 csv,2) 按 <personNode>.

中出现的 <person> 次数对人员进行排序

例子:在下面,最后一个人节点只包含1个人。因此,我想在最终输出中将此人排序在所有结果之上。

然后,应该打印所有在节点中有2个人的人。然后 3...,然后 N.

source.xml:

<personNodes>
    <personNode>
        <person>
            <id>1</id>        
            <name>john</name>
        </person>
        <person>
            <id>11</id>        
            <name>doe</name>
        </person>
    </personNode>
    <personNode>
        <person>
            <id>2</id>        
            <name>jane</name>
        </person>
    </personNode>
</personNodes>

转型:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>

    <xsl:mode on-no-match="shallow-skip"/>

    <xsl:template match="personNodes">
        <xsl:for-each select="personNode">
            <xsl:for-each select="person">
                <xsl:value-of select="concat(id, ';', name, '&#10;')"/>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

结果:

1;john
11;doe
2;jane

所需结果:

#person from 1-person node
2;jane
#persons from 2-person nodes
1;john
11;doe
#persons from 3-person nodes
...
#persons from N-person nodes

这可能吗,因为我只是通过 <xsl:value-of> 将结果打印到输出流?也许我必须在 maplist 变量中收集 csv 行,然后在最后循环再次打印到输出?

这个怎么样?

<xsl:for-each select="personNode/person">
    <xsl:sort select="../count(person)" />
    <xsl:value-of select="concat(id, ': ', name, '&#10;')"/>
</xsl:for-each>

当然要用xsl:sort

<xsl:template match="personNodes">
    <xsl:for-each select="personNode">
        <xsl:sort select="count(person)"/>
        <xsl:for-each select="person">
            <xsl:value-of select="concat(id, ': ', name, '&#10;')"/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

https://xsltfiddle.liberty-development.net/jz1PuPb/1.

如果支持高阶 sort(例如 Saxon EE 或 PE),您还可以使用

<xsl:for-each select="sort(personNode, (), function($p) { count($p/person) })">