XSL 1.0:循环分隔值

时间:2014-09-17 10:49:22

标签: xml xslt

我有以下XML:

<RESULTS>
<SEARCHRESULT RECORDS="54">
    <ROW ROWNUM="1" PKField="COUNTER">
        <COLUMN COLNUM="1" NAME="COUNTER" DATATYPE="number">1243</COLUMN>
        <COLUMN COLNUM="2" NAME="KEY" DATATYPE="number">176</COLUMN>
        <COLUMN COLNUM="3" NAME="NAME" DATATYPE="string">John Smith;Jane Doe;Alan Rickman</COLUMN>
        <COLUMN COLNUM="4" NAME="TITLE" DATATYPE="string">Secretary;Partner;Director</COLUMN>
        <COLUMN COLNUM="5" NAME="FROM_DATE" DATATYPE="date">21/04/2001;07/09/2002;27/05/2003</COLUMN>
        <COLUMN COLNUM="6" NAME="TO_DATE" DATATYPE="date">12/01/2006;14/01/2003;06/03/2006</COLUMN>
        <COLUMN COLNUM="7" NAME="DIVISION" DATATYPE="string">Retail</COLUMN>
    </ROW>
</SEARCHRESULT>

我正在创建一个XSLT文件来转换它,目前它是这样的:

KEY||NAME||TITLE||FROM_DATE||TO_DATE||DIVISION176||John Smith;
Jane Doe;
Alan Rickman||Secretary;
Partner;
Director||21/04/2001;
07/09/2002;
27/05/2003||12/01/2006;
14/01/2003;
06/03/2006||Retail

但是我试图让它像这样出来:

KEY||NAME||TITLE||FROM_DATE||TO_DATE||DIVISION
176||John Smith||Secretary||21/04/2001||12/01/2006||Retail
176||Jane Doe||Partner||07/09/2002||14/01/2003||Retail
176||Alan Rickman||Director||27/05/2003||06/03/2006||Retail

我目前正在尝试使用以下方法:

  <xsl:template name="loopOnSeperator">
<xsl:param name="String"/>
<xsl:param name="Counter" select="0" />
<xsl:variable name="sa" select="substring-after($String, $seperator)" />
  <xsl:choose>
    <xsl:when test="$sa != '' or contains($String, $seperator)">
      <xsl:call-template name="loopOnSeperator">
        <xsl:with-param name="String"    select="$sa" />
        <xsl:with-param name="Counter"   select="$Counter + 1" />
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$String" />
    </xsl:otherwise>
  </xsl:choose>

但是我特别难以使用KEY&amp; DIVISION字段。

非常感谢任何帮助,非常感谢您的时间。

1 个答案:

答案 0 :(得分:0)

我不明白你的方法(它不在任何上下文中)。让我提出一个不同的方法:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">

<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/">
    <xsl:text>KEY||NAME||TITLE||FROM_DATE||TO_DATE||DIVISION&#10;</xsl:text>

    <xsl:for-each select="RESULTS/SEARCHRESULT/ROW">
        <xsl:variable name="row" select="." />

        <xsl:variable name="names">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="string" select="$row/COLUMN[@NAME='NAME']"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="titles">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="string" select="$row/COLUMN[@NAME='TITLE']"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="from-dates">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="string" select="$row/COLUMN[@NAME='FROM_DATE']"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:variable name="to-dates">
            <xsl:call-template name="tokenize">
                <xsl:with-param name="string" select="$row/COLUMN[@NAME='TO_DATE']"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:for-each select="exsl:node-set($names)/token">
            <xsl:variable name="i" select="position()" />
            <xsl:value-of select="$row/COLUMN[@NAME='KEY']"/>
            <xsl:text>||</xsl:text>
            <xsl:value-of select="."/>
            <xsl:text>||</xsl:text>
            <xsl:value-of select="exsl:node-set($titles)/token[$i]"/>
            <xsl:text>||</xsl:text>
            <xsl:value-of select="exsl:node-set($from-dates)/token[$i]"/>
            <xsl:text>||</xsl:text>
            <xsl:value-of select="exsl:node-set($to-dates)/token[$i]"/>
            <xsl:text>||</xsl:text>
            <xsl:value-of select="$row/COLUMN[@NAME='DIVISION']"/>
            <xsl:if test="$i!=last()">
                <xsl:text>&#10;</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:if test="position()!=last()">
            <xsl:text>&#10;</xsl:text>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

<xsl:template name="tokenize">
    <xsl:param name="string"/>
    <xsl:param name="delimiter" select="';'"/>
    <xsl:choose>
        <xsl:when test="contains($string, $delimiter)">
            <token>
                <xsl:value-of select="substring-before($string, $delimiter)"/>
            </token>
            <!-- recursive call -->
            <xsl:call-template name="tokenize">
                <xsl:with-param name="string" select="substring-after($string, $delimiter)"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <token>
                <xsl:value-of select="$string"/>
            </token>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>