|
Subject: [xsl] Release Date vs. Highlight Until Date From: "john-xsl-list" <john-xsl-list@xxxxxxxx> Date: Tue, 21 Sep 2004 12:34:39 -0400 |
For testing I am using an extension function to get sysdate and a variable
instead of a parameter; hopefully I can fix that later. I am not sure why
xsl:for-each is not recommended, but it seems like I should do this with
xsl:template, xsl:call-template, xsl:apply-templates and/or whatever else is
appropriate, I just don't know how, especially "breaking out of the loop"
(comments below)
There is some redundancy in the XPath statements (for instance, the variable
$remaining is populated with something very similar to the for-each below it)
- how do I avoid that?
Thanks again,
-John
<xsl:variable name="sysdate" select="shcutil:Now()" />
<xsl:variable name="sysdatenum" select="concat( substring-before( $sysdate,
'T' ), substring-after( $sysdate, 'T' ))" />
<xsl:template match="*" mode="main">
<!-- after outputing the "highlighted" records, this number of non-highlighted
records should be output -->
<xsl:variable name="remaining" select="5 - count( //item[@template='tmpnews'
and number( concat( substring-before( sc:fld( 'highlightuntil', . ), 'T' ),
substring-after( sc:fld( 'highlightuntil', . ), 'T' ))) > $sysdatenum] )" />
<!-- this seems to work -->
<xsl:for-each select="//item[@template='tmpnews' and number( concat(
substring-before( sc:fld( 'highlightuntil', . ), 'T' ), substring-after(
sc:fld( 'highlightuntil', . ), 'T' ))) > $sysdatenum]">
<xsl:sort order="descending" select="@highlight"/>
<strong><xsl:value-of select="sc:fld( 'highlightuntil', . )" />
<xsl:value-of select="sc:path(.)" /></strong><br />
</xsl:for-each>
<!-- I am not sure how to make this one break out of the loop when $remaining
is hit -->
<xsl:for-each select="//item[@template='tmpnews' and number( concat(
substring-before( sc:fld( 'highlightuntil', . ), 'T' ), substring-after(
sc:fld( 'highlightuntil', . ), 'T' ))) <= $sysdatenum]">
<xsl:sort order="descending" select="@releasedate"/>
<xsl:value-of select="sc:fld( 'releasedate', . )" /> <xsl:value-of
select="sc:path(.)" /><br />
</xsl:for-each>
</xsl:template>
> ---------- Forwarded message ----------
> From: Robert Koberg <rob@xxxxxxxxxx>
> Date: Mon, 20 Sep 2004 17:56:01 -0700
> Subject: Re: [xsl] Release Date vs. Highlight Until Date
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
>
> xsl-list wrote:
>
> >Thanks for your suggestions. I am not sure the CMS vendor supports XSL 2.0.
> >After looking more at the system I think I'll implement an XSL extension to
> >retrieve sysdate instead of passing it everywhere I need it. I've been
> >digging deeper and found that the dates are stored as yyyyMMddTHHmmss, which I
> >don't think is xs:datetime format but should be pretty easy to parse/sort, or
> >convert to another format for parsing/sorting.
> >
> >
>
> It is the XML Schema date time or xs:dateTime datatype. You are
> lucky -- this is the easiest to sort, since it allows for simple
> string sorting. You would do something like:
>
> <xsl:template match="items">
> <xsl:apply-template select="item">
> <xsl:sort select="@release-date"/>
> </xsl:apply-templates>
> </xsl:template>
>
> >Therefore, since a single XML document contains both the IA and the content, I
> >think I can do something like (half code, half psuedo-code):
> >
> ><xsl:variable name="sysdate" select="me:function" />
> >
> >
>
> personally, I would avoid extension functions as much as humanly
> possible (you don't need them -- I never use them in the CMS, but do
> when offline for batch processing).
>
> >Is it possible to write a single XPath query that merges the equivalent of the
> >two XPath queries below (excuse my attempt at syntax) such that an
> >xsl:for-each with that as select will first process the elements matching the
> >first condition, then those matching the second condition?
> >
> >//item[@highlight_date < $sysdate]
> >
> >
> >
>
> this works, but stay away from xsl:for-each until you uinderstand
> what you are doing.
>
> >//item
> >
> >Also, to ensure I don't get the same record twice, do I just reverse the first
> >condition in the second condition? Something like:
> >
> >//item[@highlight_date < $sysdate]
> >
> >//item[@highlight_date >= $sysdate]
> >
> >
> You would want to apply-templates like I have shown above then you
> can check the position of the node (continuing on my XSL above):
>
> <xsl:template match="item">
> <xsl:if test="position() < 6">
> <xsl:apply-templates/>
> </xsl:if>
> </xsl:template>
>
> > <>
> > I think that for performance I wouldn't want this combined query to return
> > more than 5 records. It seems like this would have to do with
> > position(), but
> > that can only apply before the sort, and I want the 5 records after
> > sort. Any
> > suggestions? maybe a recursive function? anyway, I have to consider
> > alternatives for performance.
> >
> > Then within the xsl:for-each I need to sort such that those records
> > matched by
> > the highlight_date query appear first - any suggestions there?
> > Now you can can all see how lost I am.
>
> No, you are getting it, but heading in a wrong direction. Stay away from
> xsl:for-each.
>
> best,
> -Rob
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] Release Date vs. Highligh, Robert Koberg | Thread | Re: [xsl] Release Date vs. Highligh, David Carlisle |
| Re: [xsl] a Real Quickie, Kevinjohn Gallagher | Date | RE: [xsl] How to simplify this?, anton |
| Month |