0
votes

I'm running into an issue with an XSLT Transformation I'm trying to do. In the overall project, I'm working to convert an XML document to a CSV file for a database upload. The problem is the XML sends dates as an attribute value in ISO8601 format (YYYY-MM-DDT00:00:00), but for the database to take it from the CSV file, I need to convert it to MM/DD/YYYY.

Here's an XML Sample:

<GetChanged>
  <UserInformation>
   <Column Name="id" Value="555555555"/>
   <Column Name="name" Value="Kevin"/>
   <Column Name="bday" Value="1990-01-01T00:00:00"/>
  </UserInformation>
 </GetChanged>

Here's the XSLT I'm trying to use:

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

<xsl:output method="text"/>

<xsl:template match="GetChanged">
<!-- header -->
    <xsl:text>"id","name","bday"&#10;</xsl:text>
<!-- data rows -->
<xsl:for-each select="UserInformation">

    <!-- data cells -->
    <xsl:for-each select="Column[@Name='id']">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="@Value"/>
    <xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text>,</xsl:text>
    <xsl:for-each select="Column[@Name='name']">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="@Value"/>
    <xsl:text>"</xsl:text>
</xsl:for-each>
<xsl:text>,</xsl:text>
    <xsl:for-each select="Column[@Name='bday']">
    <xsl:text>"</xsl:text>
    <xsl:value-of select="format-date(@Value, '[M01]/[D01]/[Y0001]')"/>
    <xsl:text>"</xsl:text>
</xsl:for-each>
           <xsl:if test="position()!=last()">
            <xsl:text>,</xsl:text>
            </xsl:if>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

However, when I run this through Ruby using Nokogiri, I end up getting an error:

RuntimeError: runtime error: element value-of XPath evaluation returned no result

Thoughts on what I can do to format this date appropriately?

Thanks in advance!

2
Are you sure your processor supports XSLT 2.0? - michael.hor257k

2 Answers

0
votes

nokogiri depends on libxslt for XSLT.

In Nokogiri 1.6.0 and later libxml2 and libxslt are bundled with the gem, but if you want to use the system versions:

(see here for more details: https://github.com/sparklemotion/nokogiri)

libxslt only supports XSLT-1.0

A separate library called libxslt is available implementing XSLT-1.0 for libxml2

(Details see here: http://xmlsoft.org/XSLT.html)

You could work around that by using a solution like this: Convert date from DD-MMM-YYYY to YYYYMMDD format in xslt 1.0

or do some substring/concat like described here: Displaying Date as DD-MM-YYYY within XSLT/XML

0
votes

A value expressed as YYYY-MM-DDT00:00:00is not a date. Try changing :

<xsl:value-of select="format-date(@Value, '[M01]/[D01]/[Y0001]')"/>

to:

<xsl:value-of select="format-dateTime(@Value, '[M01]/[D01]/[Y0001]')"/>

Note that both functions require an XSLT 2.0 processor. If your processor supports only XSLT 1.0, you can reformat the date using string manipulations:

<xsl:value-of select="substring(@Value, 6, 2)"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="substring(@Value, 9, 2)"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="substring(@Value, 1, 4)"/>