[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Modification to The CSV to XML transform XSLT v2 from Andrew Welch


Subject: Re: [xsl] Modification to The CSV to XML transform XSLT v2 from Andrew Welch
From: "Marney Cotterill" <marney@xxxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Mar 2008 09:49:07 +1000

Thaks so much Andrew and Manfred,

I have complete control over the column names in the CSV, so no problems 
there.

I am, however wanting to run another transform over the result. Being brand 
new to XSL and XSLT, i think the best way to do this is to use a temporary tree 
stored in a variable (i'm sure that makes more sence to you than me)?

So this is my attempt at modifying the style sheet:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
    xmlns:xs="http://www.w3.org/2001/XMLSchema";
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    xmlns:fn="fn"
    exclude-result-prefixes="xs fn">

<xsl:output indent="yes" encoding="US-ASCII"/>

<xsl:param name="pathToCSV" select="'file:///c:/test.csv'"/>

<xsl:function name="fn:getTokens" as="xs:string+">
    <xsl:param name="str" as="xs:string"/>
         <xsl:analyze-string select="concat($str, ',')" 
regex='(("[^"]*")+|[^,]*),'>
              <xsl:matching-substring>
                   <xsl:sequence 
select='replace(regex-group(1), "^""|""$|("")""", "$1")'/>
              </xsl:matching-substring>
         </xsl:analyze-string>
</xsl:function>

<xsl:template match="/" name="main">
 <xsl:variable name="csvconverted">
 <xsl:choose>
   <xsl:when test="unparsed-text-available($pathToCSV)">
     <xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
     <xsl:variable name="lines" select="tokenize($csv, '&#xa;')" as="xs:string+"/>
     <xsl:variable name="elemNames" select="fn:getTokens($lines[1])" 
as="xs:string+"/>
       <root>
         <xsl:for-each select="$lines[position() > 1]">
           <row>
             <xsl:variable name="lineItems" select="fn:getTokens(.)" 
as="xs:string+"/>

             <xsl:for-each select="$elemNames">
               <xsl:variable name="pos" select="position()"/>
               <xsl:element name="{.}">
                 <xsl:value-of select="$lineItems[$pos]"/>
               </xsl:element>
             </xsl:for-each>
           </row>
         </xsl:for-each>
       </root>
     </xsl:when>
   <xsl:otherwise>
     <xsl:text>Cannot locate : </xsl:text>
     <xsl:value-of select="$pathToCSV"/>
   </xsl:otherwise>
 </xsl:choose>
 </xsl:variable>
</xsl:template>

 <xsl:template match="/root">
   <xmodexport version="4.0" generationdate="2008-03-27 22:52:04.984" 
portalid="0">
     <records>
       <xsl:apply-templates select="row">
       </xsl:apply-templates>
     </records>
   </xmodexport>
 </xsl:template>
 <xsl:template match="row">
   <record id="-1" formid="22" portalid="0" adduser="1" updateuser="1" 
approved="true" dateadded="2008-04-18 00:00:00.000" datemodified="2006-04-
18 00:00:00.000" displaydate="2006-04-17 00:00:00.000" expirydate="9999-12-
31 23:59:59.000">
     <InstanceData>
       <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
       <instance>
         <xsl:copy-of select="./*"></xsl:copy-of>
       </instance>
       <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
     </InstanceData>
   </record>
 </xsl:template>

 </xsl:stylesheet>

I have wrapped the first template in the <xsl:variable name="csvconverted">, 
and written a basic version of the next template (starting with   <xsl:template 
match="/root"> above) to transform the following output:
<root>
  <row>
     <classDay>Monday</classDay>
     <classTime>11am</classTime>.........etc

to

<xmodexport version......> 
  <records>
    <record id=-"1"................>
       <InstanceData><![CDATA[<instance>
           <classDay>Monday</classDay>
           <classTime>11am</classTime>.........etc

       </instance>]]>
     </InstanceData>
   </record>

I'm a little lost on how to call the data in from the temporary tree stored in the 
varible "csvconverted", to run this second transform template.

Any direction would be grealy appriciated.

Thanks so much,
Marney




> On 27/03/2008, Marney Cotterill <marney@xxxxxxxxxxxxxxxxxxxx> wrote:
> >  And the output XML I get from my test CSV using the above stylesheet is:
> >
> >  <?xml version="1.0" encoding="US-ASCII"?>
> >  <root>
> >     <row>
> >         <elem name="classDay">Monday</elem>
> >         <elem naem="classTime">11am</elem>
> >     </row>
> >     <row>
> >         <elem name="classDay">Tuesday</elem>
> >         <elem naem="classTime">12pm</elem>
> >     </row>
> >  </root>
> >
> >  So hence, what I would like is for the output to be:
> >  ....
> >     <row>
> >         <classDay>Monday</classDay>
> >         <classTime>11am</classTime>.......etc
> >
> >  Can we just modify this portion of the stylesheet:
> >
> >                 <elem name="{.}">
> >                 <xsl:value-of select="$lineItems[$pos]" />
> >                 </elem>
> Yes, try
>                  <xsl:element name="{.}">
>                  <xsl:value-of select="$lineItems[$pos]" />
>                  </xsl:element>
> 
> Manfred



-- 


Current Thread
Keywords