XSLT 2.0 - For-Each-Group与Tokenize结合使用

时间:2013-11-23 01:52:48

标签: xslt-2.0 xslt-grouping

我有一个带分隔符的文本blob,我想使用XSLT 2.0(saxon)格式化为HTML表格。文本blob(本例中为param myTable )包含以| c |分隔的记录。在第6次记录之后,它应该成为一个新的行。还有一个| r |我可以使用分隔符。

所以我想我会在列分隔符上使用 tokenize 来插入html列标记,然后使用 for-each-group 来插入html行标记。但是,在此之前只编写了相当简单的XSLT,我正在努力正确使用。

当使用下面的XML时,我收到一个错误,说for-each-group必须是node()类型,而不是xs:string,这就是tokenize正在生成的内容。

我怀疑我是以一种根本错误的方式接近这个,但我仍然坚持使用XSLT和这个传入的blob。任何建议表示赞赏!

<xsl:param name="myTable" />
<xsl:param name="tdSeparator" select="'\|c\|'"/>
<xsl:param name="trSeparator" select="'\|r\|'"/>

<xsl:template name="makeTable">
    <xsl:for-each-group select="fn:tokenize($myTable,$tdSeparator)" group-ending-with="*[position() mod 6 = 0]">    
    <tr>
        <xsl:for-each select="current-group()">
            <td><xsl:copy-of select="current()" /></td>
        </xsl:for-each>
    </tr>
</xsl:for-each-group>
</xsl:template>

<xsl:template match="xvar:metric1" xmlns:xvar="http://test.com/xvar/example">

<root>
    <html>
    <HEAD>
    <META content="text/html; charset=us-ascii" />
    </HEAD>
    <body>
        <p><strong>EMAIL HEADER</strong></p>        
        <p><strong>Key0: </strong> <xsl:value-of select="xvar:key0" /></p>
        <p><strong>Value1: </strong> <xsl:value-of select="xvar:value1" /></p>

etc...

    <table>
        <xsl:call-template name="makeTable" /> 
    </table>

1 个答案:

答案 0 :(得分:2)

我认为您不需要对任何内容进行分组,您只需使用tokenize两次:

<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">


<xsl:output method="html" indent="yes"/>

<xsl:param name="myTable" as="xs:string">col 1|c|col 2|c|col 3|r|1|c|2|c|3|r|4|c|5|c|6</xsl:param>
<xsl:variable name="rows" as="xs:string*" select="tokenize($myTable, $trSeparator)"/>

<xsl:param name="tdSeparator" select="'\|c\|'"/>
<xsl:param name="trSeparator" select="'\|r\|'"/>

<xsl:template name="makeTable">
  <table>
    <thead>
      <tr>
        <xsl:for-each select="tokenize($rows[1], $tdSeparator)">
          <th>
            <xsl:value-of select="."/>
          </th>
        </xsl:for-each>
      </tr>
    </thead>
    <tbody>
       <xsl:for-each select="$rows[position() gt 1]">
         <tr>
           <xsl:for-each select="tokenize(., $tdSeparator)">
             <td>
               <xsl:value-of select="."/>
             </td>
           </xsl:for-each>
         </tr>
       </xsl:for-each>
     </tbody>
   </table>
</xsl:template>

</xsl:stylesheet>

然后输出

<table>
   <thead>
      <tr>
         <th>col 1</th>
         <th>col 2</th>
         <th>col 3</th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>1</td>
         <td>2</td>
         <td>3</td>
      </tr>
      <tr>
         <td>4</td>
         <td>5</td>
         <td>6</td>
      </tr>
   </tbody>
</table>

我假设第一行有列名,但如果没有,那么你只需删除该代码,例如。

<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="xs">


<xsl:output method="html" indent="yes"/>

<xsl:param name="myTable" as="xs:string">1|c|2|c|3|r|4|c|5|c|6</xsl:param>
<xsl:variable name="rows" as="xs:string*" select="tokenize($myTable, $trSeparator)"/>

<xsl:param name="tdSeparator" select="'\|c\|'"/>
<xsl:param name="trSeparator" select="'\|r\|'"/>

<xsl:template name="makeTable">
  <table>
    <tbody>
       <xsl:for-each select="$rows">
         <tr>
           <xsl:for-each select="tokenize(., $tdSeparator)">
             <td>
               <xsl:value-of select="."/>
             </td>
           </xsl:for-each>
         </tr>
       </xsl:for-each>
     </tbody>
   </table>
</xsl:template>

</xsl:stylesheet>