|
Subject: Re: [xsl] Function converting RFC 2822 date to xsd:dateTime From: "Martynas Jusevičius martynas@xxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Tue, 9 Apr 2019 08:09:23 -0000 |
Thanks all, parse-ietf-date() makes most sense indeed. That is what I went with:
<xsl:try>
<triple>
<xsl:copy-of select="$subject"/>
<uri>&nmo;sentDate</uri>
<plainLiteral><xsl:sequence
select="parse-ietf-date($date-time)"/></plainLiteral>
</triple>
<xsl:catch>
<xsl:message><xsl:value-of select="$err:description"/>
Message ID: <xsl:value-of select="$subject"/></xsl:message>
</xsl:catch>
</xsl:try>
</xsl:template>
On Tue, Apr 9, 2019 at 5:45 AM Syd Bauman s.bauman@xxxxxxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Martynas --
>
> As Michael Kay brought up, switching to XSLT 3.0 and using
> parse-ietf-date() is probably the best way to go. And I don't pretend
> to be a good enough programmer to know if there are improvements to
> be made to your algorithm. But when dealing with unwieldy stuff like
> this, I find it very helpful to name bits of code and to use
> whitespace liberally, especially within the regular expression (using
> the 'x' flag).
>
> Here is an XSLT 2.0 program that runs a modified version of your
> function. The only other changes I've made to the function are:
> * signature of $months is now '+', not '*'
> * different mechanism for inserting colon into TZ
> * return a dateTime even when there's an error in parsing
>
> #######################
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
> xmlns:xs="http://www.w3.org/2001/XMLSchema"
> exclude-result-prefixes="#all"
> xmlns:aex="http://idunno.example.org/"
> version="2.0">
>
> <xsl:param name="dt" select="'Tue, 9 Apr 2019 00:07:24 +1200 (NZST)'" as="xs:string"/>
>
> <xsl:output method="text"/>
>
> <xsl:template match="/">
> <xsl:text>Result: </xsl:text>
> <xsl:value-of select="aex:rfc2822dateTime-to-dateTime( $dt )"/>
> <xsl:text>
</xsl:text>
> </xsl:template>
>
> <xsl:function name="aex:rfc2822dateTime-to-dateTime" as="xs:dateTime">
> <xsl:param name="date-time" as="xs:string"/>
> <xsl:variable name="months" as="xs:string+" select="
> 'Jan', 'Feb', 'Mar','Apr', 'May', 'Jun',
> 'Jul', 'Aug', 'Sep','Oct', 'Nov', 'Dec'"/>
> <xsl:analyze-string select="$date-time" flags="x" regex="
> ^
> (?: (Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+ )?
> ( 0[1-9] | [1-2]?[0-9] | 3[01] )
> \s+
> (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
> \s+
> ( 19[0-9]{{2}} | [2-9][0-9]{{3}} )
> \s+
> ( 2[0-3] | [0-1][0-9] )
> :
> ( [0-5][0-9] )
> (?: :( 60 | [0-5][0-9] ) )?
> \s+
> (
> [-\+]
> [0-9]{{2}}[0-5][0-9]
> |
> (?: UT | GMT | (?:E|C|M|P) (?:ST|DT) | [A-IK-Z] )
> )
> (\s+|\(([^\(\)]+|\\\(|\\\))*\))*$">
> <xsl:matching-substring>
> <xsl:variable name="day" select="regex-group(1)"/><!-- unused -->
> <xsl:variable name="date" select="xs:integer( regex-group(2) )"/>
> <xsl:variable name="month" select="index-of( $months, regex-group(3) )"/>
> <xsl:variable name="year" select="xs:integer( regex-group(4) )"/>
> <xsl:variable name="hour" select="xs:integer( regex-group(5) )"/>
> <xsl:variable name="minute" select="xs:integer( regex-group(6) )"/>
> <xsl:variable name="second" select="xs:integer( regex-group(7) )"/>
> <xsl:variable name="timezone" select="replace( regex-group(8),'^(...)(.*)$','$1:$2' )"/>
> <xsl:variable name="dateTimeString" select="concat(
> format-number( $year,'0001'),
> '-',
> format-number( $month,'01'),
> '-',
> format-number( $date,'01'),
> 'T',
> format-number( $hour,'01'),
> ':',
> format-number( $minute,'01'),
> ':',
> format-number( $second,'01'),
> $timezone )"/>
> <xsl:value-of select="$dateTimeString"/>
> </xsl:matching-substring>
> <xsl:non-matching-substring>
> <xsl:message>Invalid RFC 2822 datetime: <xsl:value-of select="$date-time"/></xsl:message>
> <!--
> 2 points to anyone who can say what happened at the date and time
> I've chosen to return in case of error. 2 hints: 1) I made up the
> seconds, to my knowledge it was only recorded to the minute; 2) it
> was pronounced "seventeen October nineteen forty-five" in the musical.
> -->
> <xsl:value-of select="xs:dateTime('1945-10-17T23:10:30-03:00')"/>
> </xsl:non-matching-substring>
> </xsl:analyze-string>
> </xsl:function>
>
> </xsl:stylesheet>
> #######################
>
> Hope this is at least food for thought, if not outright helpful.
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] Function converting RFC 2, Syd Bauman s.bauman@ | Thread | [xsl] Transforming large XML docume, Mukul Gandhi gandhi. |
| Re: [xsl] Transforming large XML do, Martin Honnen martin | Date | Re: [xsl] Transforming large XML do, Mukul Gandhi gandhi. |
| Month |