I have some code that loads in an xml file and applies an XSLT to it using “XslCompiledTransform”. I now need to change the code as the input file may not be XML, it could also be a CSV file. I have an XSLT that will convert the CSV to the format I want but it uses a hardcoded path. The problem I have is that the input filename will change so can I use a widecard in the name? Secondly, in code can I pass in the file as a string to an XSLT object and have the result fall out the bottom? I’ve been doing some googling and not found any code to do this. Is it even possible?
Here is the XSLT I am using. Not the hardcoded path and filename.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="fn"
exclude-result-prefixes="xs fn">
<xsl:output indent="yes" encoding="US-ASCII"/>
<xsl:param name="pathToCSV" select="'file:///C:/Downloads/inputcsv.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:choose>
<xsl:when test="unparsed-text-available($pathToCSV)">
<xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
<xsl:variable name="lines" select="tokenize($csv, '
')" as="xs:string+"/>
<xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string+"/>
<root>
<xsl:for-each select="$lines[position() > 0]">
<row>
<xsl:variable name="lineItems" select="fn:getTokens(.)" as="xs:string+"/>
<xsl:for-each select="$elemNames">
<xsl:variable name="pos" select="position()"/>
<column>
<xsl:value-of select="$lineItems[$pos]"/>
</column>
</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:template>
</xsl:stylesheet>
Well XslCompiledTransform is an XSLT 1.0 processor so using XSLT 2.0 features like
unparsed-textis not possible with XslCompiledTransform, you need to use Saxon 9 or XmlPrime or AltovaXML for XSLT 2.0.Then you can pass in a parameter to your posted stylesheet as it has a global
xsl:paramnamedpathToCSV, how you pass in that parameter depends on the API of the XSLT processor you want to use (or on its command line parameters if you simply want to execute the stylesheet from the command line).