基于xslt中的现有元素进行排序

时间:2010-06-03 03:26:02

标签: xml xslt

我想根据现有的模式集对xslt进行排序。

让我解释一下代码:

<Types>
  <Type>
     <Names>
      <Name>Ryan</Name>
     </Names>
      <Address>2344</Address>
   </Type>
    <Type>
      <Names>
       </Name>Timber</Name>
      </Names>
       <Address>1234</Address>
    </Type>
    <Type>
      <Names>
       </Name>Bryan</Name>
      </Names>
       <Address>34</Address>
    </Type>
</Types>

现在我只是调用它并使它像(所有超链接)

Ryan
Timber 
Bryan

现在我不希望对名称进行排序,但我现有模式我希望它如何显示。喜欢

Timber
Bryan
Ryan

(另外我不想在执行此操作时丢失附加到我姓名的网址)

我在考虑将早期值放在某个数组中并根据我将存储现有模式的其他数组进行排序。但我不确定如何实现这一点......

我的xslt现在看起来像这样(也可能有重复的名称)

<xsl:for-each select="/Types/Type/Names/Name/text()[generate-id()=generate-id(key('Name',.)[1])]">
<xsl:call-template name="typename">
</xsl:call-template>
</xsl:for-each>

<xsl:template name="typename">

 <li>
<a href="somelogicforurl"> <xsl:value-of select="."/> </a>
 </li>

</xsl:template>

我正在使用xsl 1.0

1 个答案:

答案 0 :(得分:1)

XSLT 1.0具有排序功能。尝试推断这个例子:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="Types">
    <xsl:element name="SortedList">
      <xsl:for-each select="Type">
        <xsl:sort select="Names/Name" />
        <xsl:element name="a">
          <xsl:attribute name="href">link</xsl:attribute>
          <xsl:value-of select="Names/Name" />
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

我不确定您想要排序的是什么,只需更改xsl:sort标记的'select'属性即可指定排序键。

或者,如果您试图强制执行特定订单,则可以强制执行:

  <xsl:template match="Types">
    <xsl:element name="SortedList">
      <xsl:apply-templates select="Names[Name='Timber']" />
      <xsl:apply-templates select="Names[Name='Bryan']" />
      <xsl:apply-templates select="Names[Name='Ryan']" />
    </xsl:element>
  </xsl:template>

  <xsl:template match="Names">
    <xsl:element name="a">
      <xsl:attribute name="href">link</xsl:attribute>
      <xsl:value-of select="Name" />
    </xsl:element>
  </xsl:template>

但是,通过这样做,您可能会错过任何事情,或者包含两次事情。排序顺序相当灵活,你甚至可以排序

<xsl:sort select="string-length(substring-before(';Timber;Bryan;Ryan',Names/Name))" />

这句话将为'Timber'返回1,为'Bryan'(长度为'; Timber;')返回8,为'Ryan'返回14(长度为'; Timber; Bryan;'),您可以排序通过这个让它们按你想要的顺序出现。这个解决方案会把你没有包含在你的排序顺序中的任何东西放在顶部,因为'substring-before'函数会返回一个空字符串,当然它的长度为0.你确实需要注意确保如果一个碰巧是另一个的子串,那么你就不会过早地匹配;例如,如果这只是小写的话,你就会过早地匹配'ryan',因为它会作为'bryan'的一部分。