Hi Vivek,
At 02:20 AM 7/17/2004, you wrote:
Hi Folks,
Thanks a lot for all your responses. Michael Kay has provided an
alternative of using position() function. What I am trying to do is
display the category heading only once if the article of that category is
found.
Often the way this kind of problem is solved in XSLT is by rethinking:
instead of "has an article of this category already been processed", think
"is this the first article of its category; if so, X, if not, Y". That is,
rather than conceptualizing the program's control flow, we leave that up to
the processor, and merely consider the nodes' organization and how that
maps to the result we want. Rather than thinking through a procedure, that
is, we simply establish a specification of what output we want for a given
input. So for example if a node is first (not temporally but within the
static scope of document order), we do one thing, otherwise something else.
One consequence of this way of working is that a processor can proceed
however it wants, as long as it gives us the specified output. It's like
ordering in a restaurant -- we send word back to the kitchen that we want
bowtie pasta with truffles (I should be so lucky), and let the chef decide
how to prepare it.
Because yours appears to be a containment test (do any preceding nodes of a
certain kind contain a certain string) rather than a simple value test, the
solution is not quite as trivial as it often is; but M. David's second
solution (that builds a string for checking, and then checks it) shows how
it can be done notwithstanding. Note his setting of that variable
<xsl:variable name="checkString">
<xsl:for-each
select="preceding-sibling::article/metadata/article-classification">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
could be optimized slightly as
<xsl:variable name="checkString">
<xsl:copy-of
select="preceding-sibling::article/metadata/article-classification"/>
</xsl:variable>
and it would work as well. This is a case where it's important that it's
*not* the same as
<xsl:variable name="checkString"
select="preceding-sibling::article/metadata/article-classification"/>
because we deliberately need all the preceding sibling article's
classifications to be gathered in a single string we can test (which
happens if they are copied into a result tree, as opposed to the nodes
themselves being bound to the variable). If it were a simple equality test,
not a string-containment test, we could use that XPath by itself in our
test (is the current node equal to any of those nodes?), and never need the
variable at all.
Cheers,
Wendell
___&&__&_&___&_&__&&&__&_&__&__&&____&&_&___&__&_&&_____&__&__&&_____&_&&_
"Thus I make my own use of the telegraph, without consulting
the directors, like the sparrows, which I perceive use it
extensively for a perch." -- Thoreau