1

Using a date:difference funtion from exslt.org date.msxsl.xsl with msxsl. If I use string literals, then the function works fine. But if I grab the strings from the xml file and put them into variables, and then use those variables for the 'difference' function, I get the following error:

msxsl.exe dummy.xml dateDifftest.xsl -o diffOut.html
Error occurred while executing stylesheet 'dateDifftest.xsl'.
Code:   0x80020009
Microsoft JScript runtime error
Wrong number of arguments or invalid property assignment
line = 954, col = 3 (line is offset from the start of the script block).
Error returned from property or method call.

I made 3 tests in this xsl. All 3 use the same datetime strings.

First test calls function with string literals. Second test calls function with variables with the strings as their content. Third test - and failing test - pulls the strings from the xml file.

So how is the variables of the 3rd test different from those of the 2nd test?

If I comment out the function call of the 3rd test this is output:

TEST-1
PT2M1S
TEST-2
2011-12-13T16:15:26
2011-12-13T16:17:27
PT2M1S
TEST-3
2011-12-13T16:15:26
2011-12-13T16:17:27

The xsl file:

<?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" />

<!-- msxsl.exe dummy.xml dateDifftest.xsl -o diffOut.html -->

<xsl:template match="/A/B/C">
    <TEST1>
        TEST-1
    <br/>
        <xsl:value-of select="date:difference('2011-12-13T16:15:26', '2011-12-13T16:17:27')"/>  <!-- outputs "PT2M1S", the difference is 2 mins and 1 sec -->
    </TEST1>
    <br/>
    <TEST2> 
        TEST-2
    <br/>
        <xsl:variable name="startTime" select="'2011-12-13T16:15:26'"/>
        <xsl:value-of select="$startTime"></xsl:value-of>
    <br/>
        <xsl:variable name="endTime" select="'2011-12-13T16:17:27'"/>
        <xsl:value-of select="$endTime"></xsl:value-of> 
    <br/>
        <xsl:value-of select="date:difference($startTime, $endTime)"/>  <!-- also outputs "PT2M1S" -->
    </TEST2>
    <br/>
    <TEST3>
        TEST-3
    <br/>
        <xsl:variable name="startTime" select="start"/>
        <xsl:value-of select="$startTime"></xsl:value-of>
    <br/>
        <xsl:variable name="endTime" select="end"/>
        <xsl:value-of select="$endTime"></xsl:value-of> 
    <br/>
    <!--    <xsl:value-of select="date:difference($startTime, $endTime)"/>--> <!-- FAILS HERE -->


    </TEST3>
</xsl:template>

Input xml file:

<A>
<B>
    <C>
        <start>2011-12-13T16:15:26</start>
        <end>2011-12-13T16:17:27</end>
    </C>
</B>
</A>

Thanks

Skippy VonDrake
  • 806
  • 8
  • 21
  • It is working for me... using xlstproc instead of msxsl. Try xsltproc -o diffOut.html dateDifftest.xsl dummy.xml – martin jakubik Dec 14 '16 at 17:14
  • I was told on a different post using this exslt.org script, that the script was meant to be used with msxsl. So I'm not sure if one should 'just use another processor if that one doesn't work' - is the right approach. Especially if I intend to use more functions from that script. But I'm new to xsl so appreciate any insights. – Skippy VonDrake Dec 14 '16 at 17:32
  • Agreed, I'm not sure it's the right approach either. In that case, why don't you tag it as msxsl to get attention from people who know msxsl ... – martin jakubik Dec 14 '16 at 17:44
  • good idea. will do – Skippy VonDrake Dec 14 '16 at 17:46
  • Why is this tagged javascript? I see that there's a "Microsoft JScript runtime error" in the log, but how is JScript involved, and is JScript really javascript? Are either of them relevant? – martin jakubik Dec 15 '16 at 09:03
  • If you look at the code that defines the function date:difference, which is what this issue revolves around, you will see it was written in javascript. – Skippy VonDrake Dec 15 '16 at 15:01
  • thanks, I didn't realize that. – martin jakubik Dec 16 '16 at 11:17

1 Answers1

2

Looking at the source you have linked to I see

<doc:args>
    <doc:arg name="date" type="string" default="''" optional="yes"></doc:arg>
    <doc:arg name="date" type="string" default="''" optional="yes"></doc:arg>
</doc:args>

so I would suggest to try to make sure on the XSLT/XPath side to pass string values as arguments

<xsl:variable name="startTime" select="string(start)"/>
    <xsl:value-of select="$startTime"></xsl:value-of>
<br/>
    <xsl:variable name="endTime" select="string(end)"/>
    <xsl:value-of select="$endTime"></xsl:value-of> 
<br/>
<xsl:value-of select="date:difference($startTime, $endTime)"/>
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • Excellent! That was the magic moment! So select="start" assigns more than just the string value?! I got a lot to learn. Thanks! – Skippy VonDrake Dec 14 '16 at 19:56
  • It looks like select="start" makes the xsl processor guess the datatype of the value. The processor guesses it's a date, but the exsl function is expecting a string, so it breaks. Whereas select="string(start)" explicitly sets the datatype to string. – martin jakubik Dec 15 '16 at 09:00
  • Thank you for that insight, Martin. Makes sense. – Skippy VonDrake Dec 17 '16 at 12:55
  • I disagree completely with the explanation 'It looks like select="start" makes the xsl processor guess the datatype of the value'. The XPath and XSLT datatypes are clearly defined in the relevant specs, there is no guessing, the expression `start` selects the `start` child element(s) of the context node so given `` the variables holds a value of type node-set. While the built-in functions like `concat` work fine whether you do `concat(start, ' bar')` or `concat('foo', ' bar')` with extension functions it is up to the implementor. – Martin Honnen Dec 17 '16 at 13:46
  • And of course it depends on the particular XSLT processor and the API exposed to extension functions whether you can only pass around atomic values like numbers or strings or also node(-set)s. With MSXML it is possible to pass in nodes but the extension function needs to be written to handle them. – Martin Honnen Dec 17 '16 at 13:48