2011-11-14 28 views
0

我需要使用XSLT 1.0製作CSV解析器。我嘗試了遞歸方法,但似乎無法匹配行結束符,所以printLine模板的輸入始終爲空。如何使用XSLT 1.0編寫CSV解析器?

<xsl:template match="/"> 
    <xsl:call-template name="printLine"> 
    <xsl:with-param name="line"> 
     <xsl:value-of select="substring-before(//csvText, '\n')"/> 
    </xsl:with-param> 
    <xsl:with-param name="remaining"> 
     <xsl:value-of select="substring-after(//csvText, '\n')"/> 
    </xsl:with-param> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="printLine"> 
<xsl:param name="line"/> 
<xsl:param name="remaining"/> 
    <xsl:value-of select="$line"/><br /> 
    <xsl:if test="remaining != ''"> 
    <xsl:call-template name="printLine"> 
     <xsl:with-param name="line"> 
     <xsl:value-of select="substring-before($remaining, '\n')"/> 
     </xsl:with-param> 
     <xsl:with-param name="remaining"> 
     <xsl:value-of select="substring-after($remaining, '\n')"/> 
     </xsl:with-param> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

回答

3

我發現瞭解決這一:

<xsl:variable name="ls"><xsl:text> 
</xsl:text></xsl:variable> 
<xsl:variable name="fs"><xsl:text> </xsl:text></xsl:variable> 

<xsl:template match="/"> 
    <xsl:call-template name="printLine"> 
    <xsl:with-param name="line" select="substring-before(//csvText, $ls)"/> 
    <xsl:with-param name="remaining" select="substring-after(//csvText, $ls)"/> 
    </xsl:call-template> 
</xsl:template> 

<xsl:template name="printLine"> 
<xsl:param name="line"/> 
<xsl:param name="remaining"/> 
    <xsl:call-template name="printFields"> 
     <xsl:with-param name="line" select="$line"/> 
    </xsl:call-template> 
    <xsl:if test="$remaining != ''"> 
    <xsl:call-template name="printLine"> 
     <xsl:with-param name="line" select="substring-before($remaining, $ls)"/> 
     <xsl:with-param name="remaining" select="substring-after($remaining, $ls)"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 

<xsl:template name="printFields"> 
    <xsl:param name="line"/> 
    <!-- render each line and access each field using the getFieldByIndex-template. Example: --> 
    <div> 
     <h3> 
      <xsl:call-template name="getFieldByIndex"> 
       <xsl:with-param name="index" select="1"/> 
       <xsl:with-param name="line" select="$line"/> 
      </xsl:call-template> 
     </h3> 
     <p> 
      <xsl:call-template name="getFieldByIndex"> 
       <xsl:with-param name="index" select="4"/> 
       <xsl:with-param name="line" select="$line"/> 
      </xsl:call-template> 
     </p> 
    </div> 
</xsl:template> 

<xsl:template name="getFieldByIndex"> 
    <xsl:param name="index"/> 
    <xsl:param name="line"/> 
    <xsl:choose> 
     <xsl:when test="$index > 0"> 
      <xsl:call-template name="getFieldByIndex"> 
       <xsl:with-param name="index" select="$index -1"/> 
       <xsl:with-param name="line" select="substring-after($line, $fs)"/> 
      </xsl:call-template> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="substring-before($line,$fs)"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

的線路和字段分隔符被存儲在LSFS變量。本示例遍歷一個製表簽名文件。模板必須針對每種用途進行定製。