0

I'm trying to follow the guidance given in this answer: time difference

But don't see why the template method is failing. Perhaps it has something to do with the namespace. And I don't understand my results for the function approach.

Input xml:

<BatchData >
<Line>
    <Batch>
        <start>2011-12-13T16:15:26</start>
        <end>2011-12-13T16:17:27</end>
    </Batch>
</Line>

xsl file:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:date="http://exslt.org/dates-and-times"
 extension-element-prefixes="date"
>
<xsl:include href="date.msxsl.xsl" /> 

<!-- msxsl.exe  myDateTestInput.xml myDateEXSLT.xsl -o dateTestOut.html-->
<!-- java -cp C:\XSL\SaxonHE9-7-0-14J\saxon9he.jar net.sf.saxon.Transform -t -s:myDateTestInput.xml -xsl:myDateEXSLT.xsl -o:dateTestOut.html  -->

<xsl:output method="html" />
<xsl:template match="/BatchData/Line/Batch">
    <html>
        <head>

        </head>

        <body>

                <table >
                    <tr>
                        <td>
                            <xsl:variable name="time-diff-dur">
                            <xsl:call-template name="date:difference">
                                <xsl:with-param name="start" select="start" />
                                <xsl:with-param name="end" select="end" />
                            </xsl:call-template>
                            </xsl:variable>
                            <!-- The above returns a duration formatted string, so convert that to seconds: -->
                            <xsl:variable name="time-diff-sec">
                                <xsl:call-template name="date:seconds">
                                   <xsl:with-param name="seconds" select="$time-diff-dur" />
                                </xsl:call-template>
                            </xsl:variable>

                            <!--
                                <xsl:variable name="time-diff-sec" select="date:seconds(date:difference(start, end))" />
                                <xsl:value-of select="$time-diff-sec"></xsl:value-of>
                            -->

                        </td>

                        </tr>
                </table>
        </body>
    </html>
</xsl:template>

I used both msxsl and Saxon9he. They both failed on the template approach but Saxon provided some error info at least. This is the errors from using the templates:

Static error at xsl:call-template on line 25 column 51 of myDateEXSLT.xsl: XTSE0650: No template exists named date:difference Static error at xsl:call-template on line 32 column 52 of myDateEXSLT.xsl: XTSE0650: No template exists named date:seconds Warning at xsl:variable on line 31 column 44 of myDateEXSLT.xsl: SXWN9001: A variable with no following sibling instructions has no effect Errors were reported during stylesheet compilation

When I comment out the templates and uncomment the function approach, I get no errors but don't know how to display the result of time-diff-sec as a table-data value. Instead the output is just the 2 datetimes of the input file.

I also used "import" instead of "include" but that didn't make any difference. Is there a difference?

So to summarize the questions:

  1. what did I do wrong with the template method?
  2. how do I display the value from the function approach?
  3. is there a difference between 'import' and 'include'?

Perhaps the former is for pulling it down from a site while the latter is for local resources.

Thanks.

This is the file date.msxsl.xsl. I'll post it here because that exslt.org site seems to be having issues. (rename the extension): date.msxsl.xsl

Community
  • 1
  • 1
Skippy VonDrake
  • 806
  • 8
  • 21

1 Answers1

2

In answer to your specific questions:

  1. "what did I do wrong with the template method?"
    <xsl:call-template> does just that: it calls a template, as specified by the name attribute. Your XSL does not define any template named either date:difference or date:seconds, so it naturally fails. If such a template were defined in an imported or included file, it might work, but the file you are including doesn't contain any such templates either.
  2. "how do I display the value from the function approach?"
    Instead of calling a non-existent template, try calling the function instead. Perusing the content of the date.msxsl.xsl file provided at the EXSLT page, it looks like the function you want is indeed called date:difference. This is intended for processing with the MSXSL library, so make sure you're using that -- attempting to process this with Saxon, for instance, will throw errors. I'm not that knowledgeable on Microsoft's XML processing stack, so I can't tell you if .NET would work -- preliminary testing invoking the .NET 1.0 and .NET 2.0 libraries from OxygenXML suggests that .NET won't work.
  3. "is there a difference between 'import' and 'include'?"
    In short, yes. See the section on Stylesheet Inclusion in the official W3 documentation.
    You use <xsl:include> above. This requires a valid HREF -- basically, a path. You supply a value of date.msxsl.xsl, so the XSL parser looks for a file named date.msxsl.xsl that is in the same directory as the XSL stylesheet file itself. Assuming you saved that file in that same directory as your own XSL, your XSL processor will find it. However, that file also does not contain any templates called either date:difference or date:seconds, so your call-template instruction fails.

Without digging into the details of extracting the date values from your source file, or formatting them in the output, I created a super-simple, quick-and-dirty example that does execute successfully when processed using the MSXSL v4.0 library.

Sample XSL:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:date="http://exslt.org/dates-and-times"
    >
    <xsl:include href="date.msxsl.xsl" />

    <xsl:template match="/">
        <TEST>
            <xsl:value-of select="date:difference('2011-12-13T16:15:26', '2011-12-13T16:17:27')"/>
        </TEST>
    </xsl:template>

</xsl:stylesheet>

The match on / is a match on the logical root. This matches on any input, so I don't bother providing any in this example.

Note also the xmlns:date declaration: the date prefix is defined in the included file (date.msxsl.xsl), but it must also be declared here in the including file.

Sample output:

<TEST xmlns:date="http://exslt.org/dates-and-times">PT2M1S</TEST>

This does appear to be working: the difference between the two date-times is indeed 2 minutes and 1 second.

This should give you a basis. Now, work out the rest, and ideally have some fun learning as you do so. :)

Eiríkr Útlendi
  • 1,160
  • 11
  • 23