|
Subject: RE: [xsl] determine the number of payment methods and specify order depending on page type being viewed From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Tue, 4 Nov 2008 15:57:08 -0000 |
> Now it happens that the fact that you're generating the
> results in a fixed order actually simplifies things for you.
> Your 'class'
> attributes can each be one of three values, "doubleLine
> completed", "doubleLine current" and "doubleLine". But
> because the elements will come in order, these do not map
> arbitrarily. Actually it's something like this:
Good work Wendell, and congratulations on your patience. I spent a few
minutes on this and gave it up: somehow it the ratio of complexity and
tedium didn't inspire me to work on it. But you've broken the back of it.
Now it just needs a way to generify it a bit more.
How about a two-pass solution?
<xsl:template match="paymentMethods">
<xsl:variable name="temp">
<xsl:apply-templates select="directDebit"/>
<xsl:apply-templates select="creditCard"/>
<xsl:apply-templates select="invoice"/>
</xsl:variable>
<xsl:apply-templates select="$temp/*" mode="add-class"
</xsl:template>
<xsl:template match="directDebit">
<directDebit>Payment by <br/>Direct Debit</directDebit>
</xsl:template>
<xsl:template match="creditCard">
<creditCard>Payment by <br/>Credit Card</creditCard>
</xsl:template>
<xsl:template match="invoice">
<invoice>Payment by <br/>Invoice</invoice>
</xsl:template>
<xsl:template match="*" mode="add-class">
<xsl:variable name="status">
<xsl:choose>
<xsl:when test="$label = local-name()">current</xsl:when>
<xsl:when test="preceding-sibling::*[local-name() =
$label]">completed</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:variable>
<li class="doubleLine {$status}"><xsl:copy-of select="node()"/></li>
</xsl:template>
Probably doesn't save many lines of code, and it runs into the 1.0
node-set() restriction, but it strikes me as capturing the logic of the
problem a bit better: if a fourth and fifth kind of payment were added,
fewer changes would be needed, as the final template has no knowledge of the
different kinds of payment.
Michael Kay
http://www.saxonica.com/
>
> ... I won't try to explain the logic of the assignment of
> values to $status in each case. You should examine and test
> it to be sure I'm right. (The logic assumes that only three
> values are possible.)
>
> But it's worth noticing I use XSLT "attribute value syntax" (the { }
> syntax) to get this value into the li/@class attribute.
>
> Cosmetically, if you don't like the extra space you get on
> the @class when $status has no value, you can write around
> that like this:
>
> <xsl:variable name="status">
> <xsl:if test="$label = 'directDebit'"> current</xsl:if>
> </xsl:variable>
> <li class="doubleLine{$status}">Payment by <br/>Direct Debit</li>
>
> The other concern here is to make sure that $label is
> available as a global parameter or variable; you said it was
> set at run time, so I assume it is.
>
> I think this handles your problem, except for one exception.
> What happens if $label is set to 'creditCard', say, but you
> have no 'creditCard' element? Currently, the stylesheet will generate:
>
> <ul>
> <li class="doubleLine completed">Payment by <br/>Direct Debit</li>
> <li class="doubleLine">Payment by <br/>Invoice</li> </ul>
>
> If your system does not have a way of preventing this from
> happening, you need to think about what you want the
> stylesheet to do if (when) it does.
>
> Finally -- notice that you don't need to test to see how many
> and which element children of 'paymentMethod' are present.
> Instead, this work is simply done by processing the input
> data: elements not present are not processed. :-) This is far
> more robust, and reflects the way XSLT is intended to work.
>
> If you need to dive in and learn how to apply and match
> templates in order to get this going -- so much the better.
> You'll never understand XSLT without this capability.
> Template matching and the idea of "tree traversal" (context
> nodes, child elements, etc. etc.) are at the heart of the language.
>
> Finally -- I have used XSLT 1.0 methods and idioms
> throughout. In XSLT 2.0, there are ways of making this more
> concise (and possibly opaque). But there's little point in
> doing this in XSLT 2.0 unless you can do it in XSLT 1.0
> (which is arguably not true of all XSLT problems).
>
> Please ask any followup questions for clarification.
>
> Cheers,
> Wendell
>
>
>
> ======================================================================
> Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx
> Mulberry Technologies, Inc. http://www.mulberrytech.com
> 17 West Jefferson Street Direct Phone: 301/315-9635
> Suite 207 Phone: 301/315-9631
> Rockville, MD 20850 Fax: 301/315-8285
> ----------------------------------------------------------------------
> Mulberry Technologies: A Consultancy Specializing in SGML
> and XML
> ======================================================================
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] determine the number of p, Wendell Piez | Thread | RE: [xsl] determine the number of p, Wendell Piez |
| Re: [xsl] determine the number of p, Wendell Piez | Date | Re: [xsl] typing the input from wit, Owen Rees |
| Month |