xsl-list
[Top] [All Lists]

Re: [xsl] Preferred declarative approach for outputting tallies based on complex triggers

2014-04-10 06:41:28
I don't find the adjective "declarative" particularly helpful here. I don't 
know how to assess whether one stylesheet is more declarative than another.

When you are processing a sequence and the result of processing one item 
depends on the results of processing previous items, there are three possible 
approaches:

* head/tail recursion

* a higher-order fold() function

* xsl:iterate

At one level all three are equivalent. head/tail recursion is probably the 
simplest and most primitive. But advising one against the others is a bit like 
arguing between "for" and "while" expressions. It's essentially a matter of 
style.

When it comes to streamability, xsl:iterate is preferred because the data flow 
is more amenable to static analysis.

Michael Kay
Saxonica

On 10 Apr 2014, at 12:12, David Rudel <fwqhgads(_at_)gmail(_dot_)com> wrote:

I have a general question for those who adhere to declarative methods.
What is your preferred regime for outputting results of analyzing a
sequence of items? The "analysis" here might be complicated, requiring
state variables, counters, and triggers (to determine when the
counting occurs). Then the "results" would be the final values of
those counters.

The main issue I'm thinking about is determining when the sequence has
been consumed so you know when to write the outputs to the result
document.

I simply use the <xsl:iterate> instruction, and then the
<xsl:on-completion> instruction takes care of this question of
determining when the sequence is finished.

From my rather inexperienced perspective, a declarative approach to
this would be something like:

<xsl:variable name="seq" select="<<find the items I need to process>>"/>

<xsl:apply-templates select="$seq" mode="analyze">
(: put a bunch of with-param elements in here to control counters and
triggers and anything you need to control the analysis :)
</xsl:apply-templates>

<xsl:template mode="analyze">
(: pick up parameters:)
(: modify the state variables and triggers:)

<xsl:if test="position() = last()">
(: output results here :)
</xsl:if>
</xsl:template>

Another method would be to use a recursive function on a sequence:

<xsl:function name="mynamespace:analyze">
<xsl:param name="seq" as="item()*">
(:several other parameters to control analysis: counters, triggers,
state variables, etc.:)

<xsl:choose>
<xsl:when test="empty($seq)">
(:output data :)
</xsl:when>
<xsl:otherwise>
(: Modify counters, triggers, and state variables based on their
current values and head($seq))
<xsl:sequence select="mynamespace:analyze(tail($seq), (: new state
variables and counters:))/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>

I was wondering what experienced users did in these cases and if
either of the above is wrong-headed.
-David

-- 

"A false conclusion, once arrived at and widely accepted is not
dislodged easily, and the less it is understood, the more tenaciously
it is held." - Cantor's Law of Preservation of Ignorance.

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--