This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Long time no axes/document question
- From: Jeni Tennison <jeni at jenitennison dot com>
- To: "Richard Mitchell" <Richard dot Mitchell at vbnonline dot com>
- Cc: "XSL" <xsl-list at lists dot mulberrytech dot com>
- Date: Thu, 20 Jun 2002 17:01:57 +0100
- Subject: Re: [xsl] Long time no axes/document question
- Organization: Jeni Tennison Consulting Ltd
- References: <03F3A585B9FE034EB571F04E4C792E220545C005@2k_exch.analysys.com>
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi Richard,
> Right then the scenario is that I want to find out if a preceding
> sibling of mine has an item in another document with a attribute
> comparison between the two. What I have so far is...
>
> <xsl:variable name="sitedefxsl" select="document('sitedef.xsl')"/>
> <xsl:when test='not(preceding-sibling::menu[(not(@system) or
> $sitedefxsl//xsl:when[xsl:call-template[@name="url_check" or
> @name="article_system"] and
> contains(@test,concat("'",translate(./@system,$UCASE,$lcase),"&apos
> ;"))]) and not(@hidden) and not(menu)])'>default.asp</xsl:when>
>
> I hope this is understandable - the bit that is messing me up is the
> ./@system because the . context is in the document not the element
> in the axes where I want it. I've done a similar thing earlier in
> the same style sheet for something not in an axes by preserving the
> conext in a variable but I can't see there is way to preserve a
> (possible) location in an axis.
This (and readability!) is a problem when you have predicates nested
inside each other. A way of pulling this out is to use an xsl:for-each
to go through the preceding-sibling menu elements one by one. That has
the advantage of allowing you to use the current node or intermediate
variables within the tests, so you can do:
<xsl:variable name="sitedefxsl" select="document('sitedef.xsl')" />
<xsl:variable name="whens"
select="$sitedefxsl//xsl:when
[xsl:call-template
[@name = 'url_check' or @name = 'article_system']]" />
<xsl:variable name="test">
<xsl:for-each select="preceding-sibling::menu">
<xsl:variable name="system"
select='concat("'",
translate(@system, $UCASE, $lcase),
"'")' />
<xsl:if test="not(@hidden) and not(menu) and
(not(@system) or
$whens[contains(@test, $system)]">true</xsl:if>
</xsl:for-each>
</xsl:variable>
...
<xsl:when test="$test != 'true'">
...
</xsl:when>
...
It's been suggested that XPath 2.0 enable you to set variables within
expressions to make this kind of thing easier, in which case you would
be able to do something like:
<xsl:when test='preceding-sibling::menu[
$system := concat("'",
lower-case(@system),
"'");
not(@hidden) and not(menu) and
(not(@system) or
$whens[contains(@test, $system)]]'>
...
</xsl:when>
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list