如何使用 Muenchian 分组 XSLT 1.0 在每个目录中按标题分组

Posted

技术标签:

【中文标题】如何使用 Muenchian 分组 XSLT 1.0 在每个目录中按标题分组【英文标题】:How to group by Title within for each catalog using Muenchian grouping XSLT 1.0 【发布时间】:2021-12-17 23:50:15 【问题描述】:

我想编写一些代码来根据每个单独的 CATALOG 标记中的 TITLE 进行分组。我使用的是 XSLT 1.0 版本。

<?xml version="1.0" encoding="UTF-8"?>
<hello>
<catalog>
  <cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
<cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>2000</year>
  </cd>
  <cd>
    <title>Unchain my heart</title>
    <artist>Joe Cocker</artist>
    <country>USA</country>
    <company>EMI</company>
    <price>8.20</price>
    <year>1987</year>
  </cd>
  
</catalog>
<catalog>
 <cd>
    <title>Ring My Bells</title>
    <artist>Enrique</artist>
    <country>USA</country>
    <company>EMI</company>
    <price>8.20</price>
    <year>1987</year>
  </cd>
  <cd>
     <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
  </cd>
</catalog>
</hello>

预期输出:

<Song>
    <Desc>From First Catalog</Desc>
    <nameofAlbum>Empire Burlesque</nameofAlbum>
    <nameofAlbum>Unchain my heart</nameofAlbum>
</Song>
<Song>
    <Desc>From Second Catalog</Desc>
    <nameofAlbum>Ring My Bells</nameofAlbum>
    <nameofAlbum>Empire Burlesque</nameofAlbum>
</Song>

要求仅根据每个 CatLog 的标题进行分组。

我曾尝试使用 Muenchian 分组,但它与所有目录标签进行分组,而我需要在目录之间进行单独分组。

【问题讨论】:

为什么不发布您的尝试以便我们修复它,而不必从头开始为您编写代码。 -- 提示:如果您想为每个目录分别按标题对 cd 进行分组,则必须在键中包含目录的 id。 【参考方案1】:

由于您想在catalog 中进行重复数据删除,我将使用generate-id() 并使用为目录元素和cd/title 生成的ID 创建一个复合键。

使用该组合键匹配cd 上的xsl:key,然后您可以遍历每个/hello/catalog,然后对于catalog 下的每个cd,您可以使用该键进行Muenchian 分组:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    
    <xsl:variable name="labels">
        <label>First</label>
        <label>Second</label>
    </xsl:variable>
    
    <xsl:key name="cd-by-catalog-and-title" match="cd" use="concat(generate-id(..), title)"/>
    
    <xsl:template match="/">
        <xsl:for-each select="/hello/catalog">
            <xsl:variable name="pos" select="position()"/>
            <Song>
                <Desc>From <xsl:value-of select="document('')/xsl:stylesheet/xsl:variable[@name='labels']/label[$pos]"/> Catalog</Desc>
                <xsl:for-each select="cd[count(. | key('cd-by-catalog-and-title', concat(generate-id(..), title))[1]) = 1]">
                    <nameofAlbum><xsl:value-of select="title"/></nameofAlbum>
                </xsl:for-each>
            </Song>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

这不适用于 XSLT 1.0 处理器。 $labelsvariable 是一个结果树片段,表达式$labels/*[position() = $pos] 会出错。 啊,你是对的。跑的时候忘记从撒克逊换成Xalan了.... 顺便说一句,我相信*[position() = $pos]可以简单地写成*[$pos] 更新为让 XSLT 使用 document('') 读取自身,然后使用 XPath in

以上是关于如何使用 Muenchian 分组 XSLT 1.0 在每个目录中按标题分组的主要内容,如果未能解决你的问题,请参考以下文章

XSLT:如何使用 Muenchian 分组将 XML 转换为文本文件

将 Muenchian 分组应用于 XSLT

XSLT / Muenchian 分组:如何从组中选择具有某些子元素的元素?

使用 XSLT 对 HTML 输出进行分组(muenchian 分组?)

XSLT 和 Muenchian 分组, 多级样本

如何改进我的 Muenchian 分组 XSLT?