代码之家  ›  专栏  ›  技术社区  ›  boogie

只打印一次一个字母标题并按字母顺序匹配项目

  •  1
  • boogie  · 技术社区  · 16 年前

    我知道我可以把一个文件读成这样的变量: <xsl:variable name=“content”select=“document('file.xml')”/>,但如何执行以下操作:

    文件:XML:

    <root>
      <child>Some</child>
      <child>Random</child>
      <child>Data</child>
      <child>Stuff</child>
    </root>
    

    使用该XML文件,我想打印:

    D
     * Data
    
    R
     * Random
    
    S
     * Stuff
     * Some
    

    意思是只打印一次标题,然后按字母顺序列出项目。我知道我可以为每个>和<xsl:sort>使用<xsl:sort>,但如何进行标题部分?

    谢谢你的帮助!

    1 回复  |  直到 16 年前
        1
  •  2
  •   Eamon Nerbonne    16 年前

    有几种可能的解决方案,这取决于您想做什么。最著名的是muenchen方法。此方法首先定义一个查找表,以查找由该键共享特定键的所有元素。然后,迭代所有键(按某种顺序),对于每个键,迭代所有键值(按某种顺序)。

    <xsl:key> 可用于创建查阅表格。如果索引第一个字母,则可以检索与特定字母对应的元素。

    <xsl:key name="child-by-first-letter" match="child" use="substring(.,1,1)"/> 
    

    现在,我们不能直接迭代所有键。但是,我们可以迭代所有值和 测试 它们是否是查阅表格中的第一个值…

    <xsl:for-each select="child[ generate-id() 
               = generate-id(key('child-by-first-letter', substring(.,1,1))[1])]"/>
        <xsl:sort select="substring(.,1,1)" /> <!--sort by first letter-->
        <xsl:value-of select="substring(.,1,1)">
        [...]
    

    上面的代码将只在生成id函数返回与生成id函数相同值的子标记上执行某些操作。 第一 具有相同第一个字母的子项列表的元素。因为generate id生成唯一的id,所以它只返回查找表中对于其特定键“第一”的子项。

    现在,您就要完成了:只需用那个特定的第一个字母迭代所有的子元素:

        <ul>
             <xsl:for-each select="key('child-by-first-letter', substring(.,1,1))">
                 <!--no sort, we'll do document order-->
                 <li><xsl:value-of select="."/></li>
             </xsl:for-each>
        </ul>
    </xsl:for-each>
    

    这叫做 Muenchian method .