[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XPath string comparison of two strings representin

Subject: Re: XPath string comparison of two strings representing calendar dates ... any counterexamples?
From: "Graydon graydon@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Aug 2017 16:43:48 -0000
Re:  XPath string comparison of two strings representin
On Wed, Aug 16, 2017 at 04:09:15PM -0000, Costello, Roger L. costello@xxxxxxxxx scripsit:
> Note that I am doing mere string comparison. I am comparing the string '20170817' against the string '20170816'.
> 
> Will the XPath always work? 

If and only if you've got a guarantee that the date format is always
correct.  That strikes me as rash.  (2017817 is going to mess things up,
for example.)  Trusting input isn't a good plan in general and dates
represented in strings in particular.

The below works; I'd be inclined to inclined to do something more
sensible with the date parsing in a production environment.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:local="http://www.example.com/local"
    exclude-result-prefixes="xs local" version="2.0">
    <xsl:output method="text" />
    <xsl:variable as="element(Test)" name="input">
        <Test>
            <Date1>20170816</Date1>
            <Date2>20170817</Date2>
        </Test>
    </xsl:variable>
    <xsl:function name="local:error">
        <xsl:message>Something, somewhere, has gone wrong.</xsl:message>
    </xsl:function>
    <xsl:function name="local:makeDate" as="xs:date">
        <xsl:param name="in" as="xs:string" />
        <xsl:choose>
            <xsl:when test="matches($in, '^(19|20)[0-9][0-9][01][1-9][0123][1-9]$')">
                <xsl:variable name="year" select="substring($in, 1, 4)" />
                <xsl:variable name="month" select="substring($in, 5, 2)" />
                <xsl:variable name="day" select="substring($in, 7, 2)" />
                <xsl:sequence select="xs:date(concat($year, '-', $month, '-', $day))" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:sequence select="local:error()" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
    <xsl:template match="/">
        <xsl:variable name="date1" as="xs:date*" select="local:makeDate($input/Date1)" />
        <xsl:variable name="date2" as="xs:date*" select="local:makeDate($input/Date2)" />
        <xsl:choose>
            <xsl:when test="$date1 instance of xs:date and $date2 instance of xs:date">
                <xsl:sequence
                    select="
                        if ($date2 gt $date1) then
                            'dates are sequential'
                        else
                            'first date may be after second date'"
                 />
            </xsl:when>
            <xsl:otherwise>
                <xsl:message>Trying to compare non-dates.</xsl:message>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>


-- Graydon

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.