xsl排序和数字

时间:2018-06-11 16:25:15

标签: xml xslt

我之前从未使用过XSL,所以很确定有一个简单的答案,但我遇到了麻烦。我正在尝试接受输入并输出一个编号的项目列表,但我正在尝试对项目进行排序,然后对它们进行编号。我要么在没有排序的情况下进行编号,要么排序正在进行,但编号出现故障。我做了一些复制/粘贴,但为了简洁起见删除了相当多的内容,我认为所有相关部分都在那里。

<workitem id="9421" type="Feature" state="Development">     
    <System.Id>9421</System.Id>
    <System.WorkItemType>Feature</System.WorkItemType>
    <workitem id="9404" type="Bug" state="Development">
        <System.Id>9404</System.Id>
        <System.WorkItemType>Bug</System.WorkItemType>
    </workitem>
    <workitem id="9422" type="User Story" state="Development">
        <System.Id>9422</System.Id>
        <System.WorkItemType>User Story</System.WorkItemType>
    </workitem>
    <workitem id="9423" type="User Story" state="Development">
        <System.Id>9423</System.Id>
        <System.WorkItemType>User Story</System.WorkItemType>
    </workitem>
    <workitem id="9424" type="User Story" state="Development">
        <System.Id>9424</System.Id>
        <System.WorkItemType>User Story</System.WorkItemType>
    </workitem>
    <workitem id="9431" type="Bug" state="Development">
        <System.Id>9431</System.Id>
        <System.WorkItemType>Bug</System.WorkItemType>
    </workitem>
</workitem>

以下是与该部分相关的xsl示例:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />

<xsl:template match="/">
  <xsl:apply-templates select="/result /workitem" />
</xsl:template>
<xsl:template match="workitem[@type='Feature']">
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <xsl:element name="h{$level}">
      <xsl:attribute name="class">
          <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
      </xsl:attribute>
    <xsl:number level="multiple" format="1. "/>
    <xsl:value-of select="System.WorkItemType" />
     #<xsl:value-of select="System.Id" />
  </xsl:element >
  <xsl:apply-templates select="workitem">
      <xsl:sort select="@type" />
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="workitem[@type='Bug']">
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <xsl:element name="h{$level}">
    <xsl:attribute name="class">
      <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
    </xsl:attribute>
    <xsl:number level="multiple" format="1. "/>
    <xsl:value-of select="System.WorkItemType" />
    #<xsl:value-of select="System.Id" />
  </xsl:element >
</xsl:template>

<xsl:template match="workitem[@type='User Story']">
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <xsl:element name="h{$level}">
    <xsl:attribute name="class">
      <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
    </xsl:attribute>
    <xsl:number level="multiple" format="1. "/>
    <xsl:value-of select="System.WorkItemType" />
    #<xsl:value-of select="System.Id" />
  </xsl:element >
</xsl:template>
</xsl:stylesheet>

我得到的输出是:

  
      
  1. 功能#9421
      1.1。 Bug#9404
      1.5。 Bug#9431
      1.2。用户故事#9422
      1.3。用户故事#9423
      1.4。用户故事#9424
  2.   

我想要的是什么:

  
      
  1. 功能#9421
      1.1。 Bug#9404
      1.2。 Bug#9431
      1.3。用户故事#9422
      1.4。用户故事#9423
      1.5。用户故事#9424
  2.   

任何智慧的话都会受到高度赞赏。

1 个答案:

答案 0 :(得分:1)

xsl:number将返回输入XML中当前元素的位置,无论您如何选择它或尝试对其进行排序。如果您想在排序后找到位置,请使用position()

<xsl:value-of select="concat(position(), '. ')" />

但是,你需要在第二个模板中做一些额外的工作,因为你需要传递父workItem的位置作为参数,以便你得到完整的数字

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />

<xsl:template match="/">
  <xsl:apply-templates select="/result/workitem">
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="workitem[@type='Feature']">
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <xsl:element name="h{$level}">
      <xsl:attribute name="class">
          <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
      </xsl:attribute>
    <xsl:value-of select="concat(position(), '. ')" />
    <xsl:value-of select="System.WorkItemType" />
     #<xsl:value-of select="System.Id" />
  </xsl:element>

  <xsl:apply-templates select="workitem">
      <xsl:with-param name="parentPos" select="position()" />
      <xsl:sort select="@type" />
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="workitem[@type='Bug' or @type='User Story']">
  <xsl:param name="parentPos"/>
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <xsl:element name="h{$level}">
    <xsl:attribute name="class">
      <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
    </xsl:attribute>
    <xsl:value-of select="concat($parentPos, '.', position(), '. ')" />
    <xsl:value-of select="System.WorkItemType" />
    #<xsl:value-of select="System.Id" />
  </xsl:element>
</xsl:template>
</xsl:stylesheet>

但是,您可能想知道可以使用CSS计数器自动编号子列表,而不是尝试在XSLT中执行此操作。

试试这个

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" html-version="5" />

<xsl:template match="/">
  <html>
    <head>
      <style>
ol {
    counter-reset: section;
    list-style-type: none;
}

li:before {
    counter-increment: section;
    content: counters(section, ".") ". ";
}

h1, h2, h3 {
    display:inline;
}
      </style>
    </head>
    <body>
      <xsl:apply-templates select="/result/workitem" />
    </body>      
  </html>
</xsl:template>

<xsl:template match="workitem[@type='Feature']">
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <ol>
    <li>
      <xsl:element name="h{$level}">
        <xsl:attribute name="class">
          <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
        </xsl:attribute>
        <xsl:value-of select="System.WorkItemType" /> #<xsl:value-of select="System.Id" />
      </xsl:element>
      <ol>
        <xsl:apply-templates select="workitem">
          <xsl:sort select="@type" />
        </xsl:apply-templates>
      </ol>
    </li>
  </ol>
</xsl:template>

<xsl:template match="workitem[@type='Bug' or @type='User Story']">
  <xsl:variable name="level" select="count(ancestor-or-self::*) "/>
  <li>
    <xsl:element name="h{$level}">
      <xsl:attribute name="class">
        <xsl:value-of select="translate(System.WorkItemType,' ','')"/>
      </xsl:attribute>
      <xsl:value-of select="System.WorkItemType" />  #<xsl:value-of select="System.Id" />
    </xsl:element>
  </li>
</xsl:template>
</xsl:stylesheet>