我在 XSLT 1.0 中嵌套分组时遇到了一些困难。问题是一些文档的元数据中有多个产品。首先,我需要按产品对结果进行分组。最后,预计还会按类型分组。实际上,我使用 XSLT 2.0 中的每组指令实现了目标。但问题是,我无法在我的项目中更改 XSLT 的版本。
如果有人能帮助我在 XSLT 1.0 中实现此要求,我将不胜感激。我想知道是否可以在那里使用 Muenchian 方法以及命名键是什么样子的。
下面是输入 xml 的示例:
<result>
<document>
<metadata>
<title>Academic Program Directors</title>
<type>typeA</type>
<product>Product1</product>
<product>Product2</product>
<product>Product3</product>
</metadata>
</document>
<document>
<metadata>
<title>Administrative Directors</title>
<type>typeA</type>
<product>Product2</product>
</metadata>
</document>
<document>
<metadata>
<title>Program Managers</title>
<type>typeB</type>
<product>Product1</product>
<product>Product3</product>
</metadata>
</document>
</result>
预期输出如下:
Product1
typeA
Academic Program Directors
typeB
Program Managers
Product2
typeA
Academic Program Directors
Administrative Directors
Product3
typeA
Academic Program Directors
typeB
Program Managers
这是 XSLT 2.0 解决方案
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/result">
<xsl:for-each-group select="document/metadata" group-by="product">
<xsl:sort select="current-grouping-key()"/>
<p style="font-weight: bold;">
<xsl:value-of select="current-grouping-key()"/>
</p>
<xsl:for-each-group select="current-group()" group-by="type">
<xsl:sort select="current-grouping-key()"/>
<p style="padding-left: 2em;">
<xsl:value-of select="current-grouping-key()"/>
</p>
<xsl:for-each select="current-group()">
<p style="padding-left: 4em;">
<xsl:value-of select="title"/>
</p>
</xsl:for-each>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
许多 XSLT 1 处理器都实现了 set:distinct
(http://exslt.org/set/functions/distinct/index.html),因此您可以使用 http://xsltransform.net/bEzjRKX 中的方法
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:set="http://exslt.org/sets" exclude-result-prefixes="set">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/result">
<xsl:variable name="metas" select="document/metadata"/>
<xsl:for-each select="set:distinct($metas/product)">
<xsl:sort select="."/>
<p style="font-weight: bold;">
<xsl:value-of select="."/>
</p>
<xsl:variable name="current-group" select="$metas[product = current()]"/>
<xsl:variable name="types" select="set:distinct($current-group/type)"/>
<xsl:for-each select="$types">
<xsl:sort select="."/>
<p style="padding-left: 2em;">
<xsl:value-of select="."/>
</p>
<xsl:for-each select="$current-group[type = current()]">
<p style="padding-left: 4em;">
<xsl:value-of select="title"/>
</p>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:transform>
使用键和 Muenchian 分组我认为问题可以通过以下方式解决
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:set="http://exslt.org/sets" exclude-result-prefixes="set">
<xsl:output method="html" indent="yes"/>
<xsl:template match="/result">
<xsl:variable name="metas" select="document/metadata"/>
<xsl:for-each select="set:distinct($metas/product)">
<xsl:sort select="."/>
<p style="font-weight: bold;">
<xsl:value-of select="."/>
</p>
<xsl:variable name="current-group" select="$metas[product = current()]"/>
<xsl:variable name="types" select="set:distinct($current-group/type)"/>
<xsl:for-each select="$types">
<xsl:sort select="."/>
<p style="padding-left: 2em;">
<xsl:value-of select="."/>
</p>
<xsl:for-each select="$current-group[type = current()]">
<p style="padding-left: 4em;">
<xsl:value-of select="title"/>
</p>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:transform>
在线 http://xsltransform.net/ehVYZNZ