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

时间:2009-09-25 07:30:18

标签: xslt

我知道我可以将文件读入这样的变量: < xsl:variable name =“content”select =“document('file.xml')”/>,但我该怎么做:

file.xml:

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

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

D
 * Data

R
 * Random

S
 * Stuff
 * Some

意味着只打印一次标题,然后按字母顺序列出项目。我知道我可以使用&lt; xsl:for-each&gt;和&lt; xsl:sort&gt;,但如何做标题部分?

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

根据您的目的,有几种可能的解决方案。最着名的是Muenchen方法。此方法首先定义查找表,以查找由该键共享特定键的所有元素。然后,您遍历所有键(按某种顺序)和每个键,遍历所有键值(按某种顺序)。

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

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

现在,我们无法以简单的方式迭代所有键。但是,我们可以迭代所有值并 test 它们是否是查找表中的第一个值...

<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)">
    [...]

上面的代码只会在子标记上执行某些操作,其中generate-id函数返回的值与generate-id函数为具有相同第一个的子项列表的 first 元素所返回的值相同信件。由于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