RE: [xsl] CSV to XML

Subject: RE: [xsl] CSV to XML
From: chun ji <cji_work@xxxxxxxxx>
Date: Tue, 13 Nov 2007 14:12:17 -0800 (PST)
Hi Michael, 
Thanks for the tips. It works after I removed this
piece code in the one you gave:  

as="xs:string()*"

Because otherwise, I see an error during the runtime: 
"
 XPST0003: SequenceType syntax error at char 0 in
{xs:string()}:
    Expected type name in SequenceType, found
<function>(
Failed to compile stylesheet. 1 error detected.
" 
Do I need to do some package update? 
* I am using "Saxon 8.9J from Saxonica", "jdk 1.6" on
a linux box. 
* And runtime command is : java -cp
/home/cji/XML/saxonsa8-9j/saxon8sa.jar
net.sf.saxon.Transform ... 


Anyway, here is the my latest xsl file. 

"
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="2.0">

        <xsl:variable name="csv"
select="unparsed-text('target.csv')"/>
        <xsl:output method="xml" indent="yes"/>
        <xsl:variable name="splitLines"
select="tokenize($csv, '&#xA;')"/>
        <xsl:variable name="columnNames"
select="tokenize($splitLines[1], ',')"/>


        <xsl:template match="/">
                <xsl:variable
name="columnNamesAsElements" as="element()*">
                        <xsl:for-each
select="$columnNames">
                                <column><xsl:value-of
select="."/></column>
                        </xsl:for-each>
                </xsl:variable>

                <xsl:variable
name="expandedColumnNames" as="xs:string()*">>
                    <xsl:for-each-group
select="$columnNamesAsElements"
group-starting-with="column[string(.)]">
                        <xsl:for-each
select="current-group()">
                            <xsl:sequence
select="string(current-group()[1])"/>
                        </xsl:for-each>
                    </xsl:for-each-group>
                </xsl:variable>


             <users>
                <xsl:for-each
select="$splitLines[position() &gt; 2]">
                    <xsl:variable name="a"
select="position()"/>
                    <xsl:call-template name="Line">
                        <xsl:with-param
name="columnNames"
select="tokenize($expandedColumnNames, ' ')" />
                        <xsl:with-param name="cells"
select="$splitLines[$a+1]" />
                    </xsl:call-template>
                </xsl:for-each>
             </users>
        </xsl:template>

        <xsl:template name="Line">
                <xsl:param name="columnNames"/>
                <xsl:param name="cells"/>
                <xsl:variable name="cellValues"
select="tokenize($cells, ',')"/>

                <xsl:for-each
select="$cellValues[position()]">
                    <xsl:variable name="a"
select="position()"/>
                    <tab>
                        <xsl:attribute name="name">
                                <xsl:value-of
select="normalize-space($columnNames[$a])"/>
                        </xsl:attribute>
                        <sub>
                                <xsl:value-of
select="normalize-space($cellValues[$a])"/>
                        </sub>
                    </tab>
                </xsl:for-each>
        </xsl:template>
</xsl:stylesheet>
" 


Thanks all for the tips. 



Chun 





--- Michael Kay <mike@xxxxxxxxxxxx> wrote:

> You could try the following. It's a bit messy
> because group-starting-with
> only works on nodes, not atomic values, so you have
> to wrap the strings in
> nodes first.
> 
> <xsl:variable name="columnNamesAsElements"
> as="element()*">
>   <xsl:for-each select="$columnNames">
>     <column><xsl:value-of select="."/></column>
>   </xsl:for-each>
> </xsl:variable>
> 
> <xsl:variable name="expandedColumnNames"
> as="xs:string()*">
>   <xsl:for-each-group
> select="$columnNamesAsElements"
>          group-starting-with="column[string(.)]">
>     <xsl:for-each select="current-group()">
>       <xsl:sequence
> select="string(current-group()[1])"/>
>     </xsl:for-each>
>   </xsl:for-each-group>
> </xsl:variable>
> 
> then use expandedColumnNames where you used
> columnNames before.
> 
> Michael Kay
> http://www.saxonica.com/ 
> 
> > -----Original Message-----
> > From: chun ji [mailto:cji_work@xxxxxxxxx] 
> > Sent: 13 November 2007 19:13
> > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> > Subject: [xsl] CSV to XML 
> > 
> > 
> > Hi all, 
> > 
> > I know how to convert this CSV file into Xml one
> by this XSL 
> > file in XSLT2.0. 
> > 
> > 1. CSV file: 
> > X1,X1,X2,X2,X2,X3
> > a1,a2,a3,a4,a5,a6
> > 
> > 2. XSL file: 
> > <xsl:stylesheet
> > xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
> > version="2.0">
> >         <xsl:variable name="csv"
> > select="unparsed-text('target.csv')"/>
> >         <xsl:output method="xml" indent="yes"/>
> >         <xsl:variable name="splitLines"
> > select="tokenize($csv, '
')"/>
> >         <xsl:variable name="columnNames"
> > select="tokenize($splitLines[1], ',')"/>
> > 
> >         <xsl:template match="/">
> >              <users>
> >                 <xsl:for-each
> > select="$splitLines[position() &gt; 2]">
> >                     <xsl:variable name="a"
> > select="position()"/>
> >                     <xsl:call-template
> name="Line">
> >                         <xsl:with-param
> > name="columnNames" select="$columnNames" />
> >                         <xsl:with-param
> name="cells"
> > select="$splitLines[$a+1]" />
> >                     </xsl:call-template>
> >                 </xsl:for-each>
> >              </users>
> >         </xsl:template>
> > 
> >         <xsl:template name="Line">
> >                 <xsl:param name="columnNames"/>
> >                 <xsl:param name="cells"/>
> >                 <xsl:variable name="cellValues"
> > select="tokenize($cells, ',')"/>
> > 
> >                 <xsl:for-each
> > select="$cellValues[position()]">
> >                     <xsl:variable name="a"
> > select="position()"/>
> >                     <tab>
> >                         <xsl:attribute
> name="name">
> >                                 <xsl:value-of 
> > select="normalize-space($columnNames[$a])"/>
> >                         </xsl:attribute>
> >                         <sub>
> >                                 <xsl:value-of 
> > select="normalize-space($cellValues[$a])"/>
> >                         </sub>
> >                     </tab>
> >                 </xsl:for-each>
> >         </xsl:template>
> > </xsl:stylesheet>
> > 
> > 3. XML output. 
> > <?xml version="1.0" encoding="UTF-8"?>
> > <users>
> >    <tab name="X1">
> >       <sub>a1</sub>
> >    </tab>
> >    <tab name="X1">
> >       <sub>a2</sub>
> >    </tab>
> >    <tab name="X2">
> >       <sub>a3</sub>
> >    </tab>
> >    <tab name="X2">
> >       <sub>a4</sub>
> >    </tab>
> >    <tab name="X2">
> >       <sub>a5</sub>
> >    </tab>
> >    <tab name="X3">
> >       <sub>a6</sub>
> >    </tab>
> > </users>
> > 
> > Now the CSV file has been changed to as: 
> > "
> > X1,,X2,,,X3
> > a1,a2,a3,a4,a5,a6
> > "
> > and is expeting the same XML output... I am
> blocked.
> > So can someone give me some help for this ? 
> > 
> >  
> > 
> > Thanks a lot 
> > 
> > 
> > Chun
> > 
> > 
> >       
> >
>
______________________________________________________________
> > ______________________
> > Be a better pen pal. 
> > Text or chat with friends inside Yahoo! Mail. See
> how.  
> > http://overview.mail.yahoo.com/
> 
> 



      ____________________________________________________________________________________
Get easy, one-click access to your favorites. 
Make Yahoo! your homepage.
http://www.yahoo.com/r/hs 

Current Thread
  • [xsl] CSV to XML, (continued)
      • chun ji - Tue, 13 Nov 2007 11:13:01 -0800 (PST)
        • mozer - Tue, 13 Nov 2007 20:18:54 +0100
        • Steve - Tue, 13 Nov 2007 14:23:27 -0500
        • Michael Kay - Tue, 13 Nov 2007 20:24:53 -0000
        • chun ji - Tue, 13 Nov 2007 14:12:17 -0800 (PST) <=
        • Michael Kay - Tue, 13 Nov 2007 23:15:14 -0000