Search code examples
xmlcsvxsltxslt-2.0

Use XSL and Display Data Vertically in CSV File


Data Source

I am trying to take the following XML structure, and transform it into a CSV file with XSL.

<Root>
  <Row>
    <Employee>Harry</Employee>
    <Employees_Manager_1>Ron</Employees_Manager_1>
    <Employees_Manager_2>Hermione</Employees_Manager_2>
    <Employees_Manager_3>Ginni</Employees_Manager_3>
  </Row>
  <Row>
    <Employee>Ross</Employee>
    <Employees_Manager_1>Emma</Employees_Manager_1>
    <Employees_Manager_2>Monica</Employees_Manager_2>
    <Employees_Manager_3>Rachel</Employees_Manager_3>
  </Row>
</Root>

Desired Output in CSV

    Harry,Ron,
    Harry,Hermione,
    Harry,Ginni,
    Ross,Emma,
    Ross,Monica,
    Ross,Rachel,

Failed Attempt

I am a beginner in XML/XSL, and so far I only know how to use the following:

<xsl:template match="Root">
  <xsl:for-each select="Row">
    <xsl:value-of select="Employee"/>
    <text>,</text>
    <xsl:value-of select="Employees_Manager_1"/>
    <text>,</text>
    <xsl:value-of select="Employees_Manager_2"/>
    <text>,</text>
    <xsl:value-of select="Employees_Manager_3"/>
    <text>,</text>
    <endTag>&#xD;&#xA;</endTag>
  </xsl:for-each>
</xsl:template>

I am getting this result:

    Harry, Ron, Hermione, Ginni,
    Ross, Emma, Monica, Rachel,

Question

Is there a way to get my desired output with XSL? Thank you.


Solution

  • In XSLT 2/3, to map XML to CSV, I usually apply-templates to the elements supposed to be mapped to a line in the CSV and then output any items for each line using xsl:value-of with a separator attribute:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        exclude-result-prefixes="#all"
        version="3.0">
    
      <xsl:output method="text"/>
    
      <xsl:template match="/">
        <xsl:apply-templates select="Root/Row/(* except Employee)"/>
      </xsl:template>
    
      <xsl:template match="Row/*">
          <xsl:value-of select="preceding-sibling::Employee, ." separator=","/>
          <xsl:text>&#10;</xsl:text>
      </xsl:template>
    
    </xsl:stylesheet>
    

    https://xsltfiddle.liberty-development.net/pPJ8LV6