简体   繁体   中英

Title in CSV file when converting from XML to CSV using XML

I am trying to convert the XML to CSV using XSLT , I am getting the record but I need title in CSV file.

Eg:

Name    EmailAddress
Gaurav   Gaur@yopmail.com
Satya    Satya@yopmail.com

XML

<?xml version="1.0"?>
<SearchResults>
<Columns>
    <Column Label="Name">Name</Column>
    <Column Label="Email Addresses">EmailAddress</Column>
</Columns>
<Rows>
    <Row>
        <Name>Gaurav Joshi</Name>
        <EmailAddress>ybenipohe-3888@yopmail.com</EmailAddress>

    </Row>
    <Row>
        <Name>Satya</Name>
        <EmailAddress>eqaddoxoqu-8703@yopmail.com</EmailAddress>
     </Row>

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <!-- This transform is used to generate a CSV file.-->
  <xsl:output method="text" indent="no" />
  <xsl:template match="/">
    <xsl:apply-templates select="/SearchResults/Rows/Row" />
  </xsl:template>
  <xsl:template match="/SearchResults/Rows/Row">
    <xsl:text>&quot;</xsl:text>
    <xsl:value-of select="position()" />
    <xsl:text>&quot;</xsl:text>
    <xsl:for-each select="*">
      <xsl:text>,&quot;</xsl:text>
      <xsl:value-of select="." />
      <xsl:text>&quot;</xsl:text>
    </xsl:for-each>
    <xsl:text>
    </xsl:text>
  </xsl:template>
  <xsl:template match="/SearchResults/Columns" />
</xsl:stylesheet>

You currently have a template matching /SearchResults/Columns , which is actually redundant at the moment, because you don't have any templates that explicitly select these (Due to you doing <xsl:apply-templates select="/SearchResults/Rows/Row" /> ).

But you can easily adapt it to output the headings, and then you would just need an xsl:apply-templates to select it.

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <!-- This transform is used to generate a CSV file.-->
  <xsl:output method="text" indent="no" />

  <xsl:template match="/">
    <xsl:apply-templates select="/SearchResults/Columns" />
    <xsl:apply-templates select="/SearchResults/Rows/Row" />
  </xsl:template>

  <xsl:template match="Row">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="position()" />
    <xsl:text>"</xsl:text>
    <xsl:for-each select="*">
      <xsl:text>,"</xsl:text>
      <xsl:value-of select="." />
      <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

  <xsl:template match="Columns">
    <xsl:text>"Row"</xsl:text>
    <xsl:for-each select="Column">
       <xsl:text>,"</xsl:text>
       <xsl:value-of select="@Label" />
       <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

But this makes the (big?) assumption that the child nodes of each Row are in the same order as the relevant Column nodes. If this is not the case, you have work to do. Try replacing the template matching Row with this one instead

  <xsl:template match="Row">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="position()" />
    <xsl:text>"</xsl:text>
    <xsl:variable name="Row" select="." />
    <xsl:for-each select="/SearchResults/Columns/Column">
      <xsl:text>,"</xsl:text>
      <xsl:value-of select="$Row/*[name() = current()]" />
      <xsl:text>"</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM