Home > Enterprise >  XSLT to covert XML file to csv with to total record count added in Trailer
XSLT to covert XML file to csv with to total record count added in Trailer

Time:07-19

I am new to XSLT and really hoping someone can help me out. I get an XML document from program and I need to be able to convert this to a CSV file with footer record having total number of row in result file. Here is an example of the XML File: I tried some readily available xslt but I getting error.

<Content xmlns="http://www.taleo.com/ws/integration/toolkit/2005/07">
  <ExportXML>
    <record>
      <field name="Number">12663342</field>
      <field name="FileName">Document.pdf</field>
      <field name="LastModificationDate">2022-07-17 16:31:29</field>
    </record>
    <record>
      <field name="Number">12663324</field>
      <field name="FileName">Rishabh's| Resume.pdf</field>
      <field name="LastModificationDate">2022-07-17 06:38:44</field>
    </record>
  </ExportXML>
</Content>

here is the xslt code

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:itk="http://www.taleo.com/ws/integration/toolkit/2005/07" xmlns:fct="http://www.taleo.com/xsl_functions" xmlns:quer="http://www.taleo.com/ws/integration/query">
    <xsl:output method="text" encoding="UTF-8"/>
    <xsl:param name="csvDelimiter">"</xsl:param>
    <xsl:param name="csvQuoteCharacter">"</xsl:param>
    <!-- ======================================= -->
    <!-- Root template. -->
    <!-- ======================================= -->
    <xsl:template match="/">
        
        <!-- Process records. -->
        <xsl:apply-templates select="//itk:record"/>
        <!-- Build trailer record. -->
        <xsl:text>TRL</xsl:text>
        <xsl:value-of select="format-number(count(//itk:record), '000000000')"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:template>

    
    <!-- ======================================= -->
    <!-- Template matching each record. -->
    <!-- ======================================= -->
    <xsl:template match="itk:record">
        <xsl:for-each select="itk:field">
            <xsl:value-of select="fct:quote(.)"/>
            <xsl:if test="position() != last()">
                <xsl:value-of select="$csvDelimiter"/>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
        
        <xsl:function name="fct:nvl">
        <xsl:param name="value"/>
        <xsl:param name="replace-with"/>
        <xsl:choose>
            <xsl:when test="string-length($value) &gt; 0">
                <xsl:value-of select="$value"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$replace-with"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
    </xsl:template>
    
        <!-- ======================================= -->
    <!-- Quote a value if it contains the csvDelimiter or the csvQuoteCharacter. -->
    <!-- ======================================= -->
    <xsl:function name="fct:quote">
        <xsl:param name="value"/>
        <xsl:choose>
            <xsl:when test="contains($value, $csvDelimiter) or contains($value, $csvQuoteCharacter)">
                <xsl:value-of select="$csvQuoteCharacter"/>
                <xsl:value-of select="replace($value, $csvQuoteCharacter, concat($csvQuoteCharacter, $csvQuoteCharacter))"/>
                <xsl:value-of select="$csvQuoteCharacter"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$value"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
    
</xsl:stylesheet>

Expected result should be csv with below format file format

12663342|Document.pdf|2022-07-17 16:31:29
12663324|"Rishabh's| Resume.pdf"|2022-07-17 06:38:44
TRL|2

I am facing error with above code. your help will be greatly appreciated

Thanks, Sandeep

CodePudding user response:

You don't state what error you get, but I assume it's that the xsl:function element that declares the fct:nvl function is a child of an xsl:template element rather than a child of the xsl:stylesheet element. Just move the xsl:function up a level so that it's a child of the stylesheet.

  • Related