如何在 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, ' ')"/>
</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>
将结果打印到输出流?也许我必须在 map
或 list
变量中收集 csv 行,然后在最后循环再次打印到输出?
这个怎么样?
<xsl:for-each select="personNode/person">
<xsl:sort select="../count(person)" />
<xsl:value-of select="concat(id, ': ', name, ' ')"/>
</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, ' ')"/>
</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) })">
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, ' ')"/>
</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>
将结果打印到输出流?也许我必须在 map
或 list
变量中收集 csv 行,然后在最后循环再次打印到输出?
这个怎么样?
<xsl:for-each select="personNode/person">
<xsl:sort select="../count(person)" />
<xsl:value-of select="concat(id, ': ', name, ' ')"/>
</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, ' ')"/>
</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) })">