XSLT如何将序列分成子序列

时间:2017-04-30 02:50:46

标签: xslt grouping partitioning

我有一个包含字符串序列的XML文件

<ModsConfigData>
  <buildNumber>1393</buildNumber>
  <activeMods>
    <li>Core</li>
    <li>ZhentarFix</li>
    <li>WorldPawnGC</li>
    <li>HugsLib</li>
    <!-- more entries -->
  </activeMods>
</ModsConfigData>

我希望将长元素列表分成给定长度的子集 - 在我的例子中,长度为5。目的是然后使用子集来生成一个表格结构,该表格结构为五个跨越,但需要多行才能使用完整列表。

我希望实现的输出是BBCode的子集,如下所示:

[table]
  [tr]
    [td]Core[/td][td]ZhentarFix[/td][td]WorldPawnGC[/td] ...
  [/tr]
  [tr]
    [td] ... (next set of five entries) [/td]
  [/tr]
[/table]

它看起来像是一组查询给我。可能有办法做for-each循环,而position()mod 5或position div 5可能是达到目标的一种方法。我对分组指令不太熟悉,甚至猜测是否可以提供帮助。

这就是我目前使用的,欢迎任何改进。

             

    <xsl:variable name="modsConfigFile" select="document('ModsConfig.xml')"/>
    <xsl:variable name="groupSize" select="5"/>

    <xsl:template match="/ModsConfigData/activeMods">
        <xsl:text>[hr][table]</xsl:text>
        <xsl:value-of>           
            <xsl:apply-templates
                select="li[position() mod $groupSize = 1]"/>
        </xsl:value-of>
        <xsl:text>[/table]</xsl:text>
    </xsl:template>  

    <xsl:template match="li">
        <xsl:text>[tr]</xsl:text>
            <xsl:apply-templates select= 
                ".|following-sibling::li[position() &lt; $groupSize]"/>
        <xsl:text>[/tr]</xsl:text>
        <br/>
    </xsl:template>

    <xsl:template match="li" >
        <xsl:text>[td]</xsl:text>
            <xsl:value-of select="."/>
        <xsl:text>[/td]</xsl:text>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

  

这就是我目前使用的,

你不能“使用”那个,因为它不起作用。它不起作用,因为(除其他外):

  1. 您无法在xsl:apply-templates内放置xsl-value-of;和

  2. 您有两个匹配li的模板,它们之间没有区别。

  3. 要按照您的方式开始,您需要这样做:

    XSLT 1.0

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    
    <xsl:variable name="groupSize" select="5"/>
    
    <xsl:template match="/ModsConfigData">
        <xsl:text>[table]&#10;</xsl:text>
        <xsl:apply-templates select="activeMods/li[position() mod $groupSize = 1]"/>
        <xsl:text>[/table]</xsl:text>
    </xsl:template>  
    
    <xsl:template match="li">
        <xsl:text>  [tr]&#10;    </xsl:text>
        <xsl:apply-templates select= ". | following-sibling::li[position() &lt; $groupSize]" mode="cell"/>
        <xsl:text>&#10;  [/tr]&#10;</xsl:text>
    </xsl:template>
    
    <xsl:template match="li" mode="cell">
        <xsl:text>[td]</xsl:text>
            <xsl:value-of select="."/>
        <xsl:text>[/td]</xsl:text>
    </xsl:template>
    
    </xsl:stylesheet>
    

    当以上内容应用于以下测试输入时:

    <强> XML

    <ModsConfigData>
        <buildNumber>1393</buildNumber>
        <activeMods>
            <li>A</li>
            <li>B</li>
            <li>C</li>
            <li>D</li>
            <li>E</li>
            <li>F</li>
            <li>G</li>
            <li>H</li>
            <li>I</li>
            <li>J</li>
            <li>K</li>
            <li>L</li>
        </activeMods>
    </ModsConfigData>
    

    结果将是:

    [table]
      [tr]
        [td]A[/td][td]B[/td][td]C[/td][td]D[/td][td]E[/td]
      [/tr]
      [tr]
        [td]F[/td][td]G[/td][td]H[/td][td]I[/td][td]J[/td]
      [/tr]
      [tr]
        [td]K[/td][td]L[/td]
      [/tr]
    [/table]