mad_typist
mad_typist

Reputation: 196

How do I write an XSLT to transform XML to CSV?

I'm trying to write an XSLT that will transform an XML document that I have to a CSV file. Here's a sample of the XML:

<?xml version="1.0" encoding="utf-8"?>
<Import>
    <Users>
        <User ID="user_1" EmailAddress="[email protected]">
            <Contact FirstName="John" LastName="Doe" />
            <Address Street1="808 Elm St" City="Anywhere" State="NY" />
        </User>

        <User ID="user_2" EmailAddress="[email protected]">
            <Contact FirstName="Jane" LastName="Noone" />
            <Address Street1="123 Some Rd" City="Anywhere" State="NY" />
        </User>     
    </Users>
</Import>

What I want is an XSLT that will output like so:

John,Doe,808 Elm St,Anywhere,NY
Jane,Noone,123 Some Rd,Anywhere,NY

I think I have the C# code correct to initiate the transform, but just in case I don't, here's that code as well:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.Configuration;

namespace UserTransform
{
    class Program
    {
        static void Main(string[] args)
        {
            string oldXML = ConfigurationSettings.AppSettings["XMLToBeTransformed"];
            string xsltLocation = ConfigurationSettings.AppSettings["XSLTfile"];
            string newCSV = ConfigurationSettings.AppSettings["NewCSVLocation"];

            XslCompiledTransform transform = new XslCompiledTransform();
            transform.Load(xsltLocation);
            transform.Transform(oldXML, newCSV);
        }
    }
}

Upvotes: 11

Views: 40741

Answers (3)

Evans
Evans

Reputation:

I always prefer to let the browser process the XML relieving the server to carry on with more demanding job. That said, here's a sample XSLT that should translate your XML and present it in a CSV format as shown above.

Hope this sample code helps, if not, let me know.

<xsl:stylesheet version="1.0">
    <xsl:template match="/">
        <table>
            <xsl:for-each select="//User">
                <tr>
                    <td>
                        <xsl:value-of select="conat('[', @ID, ']')"/>
                        <xsl:value-of select="','"/>
                        <xsl:value-of select="Contact/@FirstName"/>
                        <xsl:value-of select="','"/>
                        <xsl:value-of select="Contact/@LastName"/>
                        <xsl:value-of select="','"/>
                        <xsl:value-of select="Address/@Street1"/>
                        <xsl:value-of select="','"/>
                        <xsl:value-of select="Address/@City"/>
                        <xsl:value-of select="','"/>
                        <xsl:value-of select="Address/@State"/>
                    </td>
                </tr>
             </xsl:for-each>
        </table>
     </xsl:template>
</xsl:stylesheet>

Upvotes: 7

Andrew G. Johnson
Andrew G. Johnson

Reputation: 26993

In my experience I've always used XSLT on the client side of things not server side which is what you seem to be attempting with C#

Upvotes: -3

Welbog
Welbog

Reputation: 60418

Create a template that matches all users, then pull out the information you need in the order you want:

<xsl:template match="//User">
  <xsl:value-of select="Contact/@FirstName"/>,
  <xsl:value-of select="Contact/@LastName"/>,
  <!--etc-->
</xsl:template>

Obviously you'll need to make sure whitespace is handled the way you want it to be, with newlines in the right places. I'll leave this as an exercise to the reader.

Upvotes: 17

Related Questions