Xml 按子元素对XSLT进行排序和分组

Xml 按子元素对XSLT进行排序和分组,xml,xslt,sorting,grouping,Xml,Xslt,Sorting,Grouping,`我有一个XML文件,其中包含许多“Entry”节点。在每个“条目”节点中,通常有一个“年”和“标题”子节点 我正在尝试生成如下所示的HTML输出: 2012 Title Title 2011 Title 2010 Title Title root Entry Title Year <root> <Entry> <Title>Num 1</Ti

`我有一个XML文件,其中包含许多“Entry”节点。在每个“条目”节点中,通常有一个“年”和“标题”子节点

我正在尝试生成如下所示的HTML输出:

2012
    Title
    Title

2011
    Title

2010
    Title
    Title
root
    Entry
        Title
        Year

<root>
    <Entry>
        <Title>Num 1</Title>
        <Year>1991</Year>
    </Entry>
    <Entry>
        <Title>Num 2</Title>
        <Year>2011</Year>
    </Entry>
    <Entry>
        <Title>Num 3</Title>
        <Year>2012</Year>
    </Entry>
    <Entry>
        <Title>Num 4</Title>
        <Year>2012</Year>
    </Entry>
</root>
只要存在具有唯一年份的条目,这种模式就应该持续。我很难让它只打印一次年度。我可以让它每年打印一次,但它只打印一个(假设是第一个)条目的标题。我可以让它打印每个条目的年份,但它会显示每个条目的年份。我使用了变量组合、生成ID和密钥,但遇到了所描述的问题(我可能每个都做错了)

  • 年数、参赛人数或每年/组参赛人数没有限制
  • 每年只能显示一次
就HTML而言,我希望每个子组(共享一年)都在自己的有序列表中,但如果这不可能,我也不会感到惊讶

我正在处理的XML文件的一般模式如下:

2012
    Title
    Title

2011
    Title

2010
    Title
    Title
root
    Entry
        Title
        Year

<root>
    <Entry>
        <Title>Num 1</Title>
        <Year>1991</Year>
    </Entry>
    <Entry>
        <Title>Num 2</Title>
        <Year>2011</Year>
    </Entry>
    <Entry>
        <Title>Num 3</Title>
        <Year>2012</Year>
    </Entry>
    <Entry>
        <Title>Num 4</Title>
        <Year>2012</Year>
    </Entry>
</root>
根目录
进入
标题
年
数字1
1991
数字2
2011
数字3
2012
数字4
2012
XSL版本1.0或2.0可以

这里是条目的模板匹配(它只需要元素并将所有内容放在一行列表项中)。
  • 
    a href=”http://thisisnot.real/publications/
    "
    /a
    , 
    ,
    在里面
    , 
    页
    ,
    一月
    二月
    前进
    四月
    也许
    六月
    七月
    八月
    九月
    十月
    十一月
    十二月
    ()
    接受率:
    ()
    

  • 这里有一个2.0选项

    XML输入

    <root>
      <Entry>
        <Title>Title B</Title>
        <Year>2010</Year>
      </Entry>
      <Entry>
        <Title>Title A</Title>
        <Year>2010</Year>
      </Entry>
      <Entry>
        <Title>Title B</Title>
        <Year>2012</Year>
      </Entry>
      <Entry>
        <Title>Title A</Title>
        <Year>2011</Year>
      </Entry>
      <Entry>
        <Title>Title A</Title>
        <Year>2012</Year>
      </Entry>
    </root>
    
    
    标题B
    2010
    标题A
    2010
    标题B
    2012
    标题A
    2011
    标题A
    2012
    
    XSLT2.0

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="root">
        <html>
          <xsl:for-each-group select="Entry" group-by="Year">
            <xsl:sort select="Year" data-type="number" order="descending"/>
            <p><xsl:value-of select="Year"/></p>
            <ol>
              <xsl:apply-templates select="current-group()/Title">
                <xsl:sort select="." data-type="text" order="ascending"/>
              </xsl:apply-templates>
            </ol>
          </xsl:for-each-group>
        </html>
      </xsl:template>
    
      <xsl:template match="Title">
        <li><xsl:value-of select="."/></li>
      </xsl:template>
    
    </xsl:stylesheet>
    
    
    

  • HTML输出(代码)

    
    2012年

  • 标题A
  • 标题B
  • 2011年

  • 标题A
  • 2010年

  • 标题A
  • 标题B
  • HTML输出(显示)

    2012年

  • 标题A
  • 标题B
  • 2011年

  • 标题A
  • 2010年

  • 标题A
  • 标题B

  • 您有没有一个很好的小示例文件,可以从中复制(部分)此处的内容?谢谢!我对上面的代码做了一些修改,但是当我预览结果时,XMLPad-Pro说xsl:sort必须在xsl:for-each或xsl:apply模板中。似乎它不喜欢xsl:for each group中的排序。@BenHayes-当您更改代码时,是否在
    xsl:sort
    之前添加了任何内容?它必须是每个组的
    xsl:for
    的第一个子项。如果没有,可能是XMLPad Pro的问题<在
    xsl:for each group
    ::中肯定允许使用code>xsl:sort。它仍然是for each group中最顶层的元素。我在IE和XMLSpy中尝试了它,它似乎只是吐出了每个条目的内容,忽略了xsl文件中的html/样式。我有一个与“Entry”匹配的模板,它从每个条目中将节点添加到有序列表中,并为每个列表项添加样式。@BenHayes-IE是XSLT 1.0,所以xsl:for each group不起作用。确保使用2.0处理器。另外,您可以将修改后的XSL添加到问题中吗?我很难想象你的模板是什么样子。我在年度输出中添加了和标签。我把它改为按月份(数字)排序,而不是按标题排序。我不需要“Title”模板,因为“Entry”模板应该输出其子项。
    <html>
       <p>2012</p>
       <ol>
          <li>Title A</li>
          <li>Title B</li>
       </ol>
       <p>2011</p>
       <ol>
          <li>Title A</li>
       </ol>
       <p>2010</p>
       <ol>
          <li>Title A</li>
          <li>Title B</li>
       </ol>
    </html>