Reputation: 1064
I have a situation where I am trying to match a number of possible paths to a template in the following way:
<xsl:template match="blah">
<xsl:apply-templates select="foo/*/baz" mode="someMode"/>
</xsl:template>
<xsl:template match="*" mode="someMode">
<xsl:if test="current() != 'foo/bar/baz' and
current() ! ='foo/bam/baz'">
<!-- Process here -->
</xsl:if>
</xsl:template>
So as you can see, there can be any number of elements under 'foo' which have the 'baz' element (for example, 'bar', 'bam', 'bal', 'bav', etc.) but I know about only 2 of them, 'bar' and 'bam'. I don't want to process these ones, but the others I do. Unfortunately, the current() method is not returning the path that was matched, so the test always succeeds (even when the path is 'foo/bar/baz' or 'foo/bam/baz'.
How can I retrieve the path that was matched in the if-test?
Please note: I can't have other xsl:template elements that specifically match 'foo/bar/baz' and 'foo/bam/baz', as they are being processed in other places (in other ways).
Upvotes: 2
Views: 137
Reputation: 25034
If you have other templates with mode="someMode" that match foo/bar/baz and foo/bam/baz, then your template that matches * in that mode will never fire on such elements, and the test in your conditional will always be true even if you re-formulate it to say what you want.
If you're not entirely sure that a given element that would have matched the pattern foo/bar/baz or foo/bam/baz is matched elsewhere and you want to make sure that the code inside your if
statement won't fire for it, you can recast your test as
test="not(self::baz/parent::bar/parent::foo
or self::baz/parent::bam/parent::foo)"
Many XSLT programmers would write it differently, though by adding that test in a predicate on the match pattern for the template:
<xsl:template mode="someMode"
match="*[not(self::baz/parent::bar/parent::foo
or self::baz/parent::bam/parent::foo)]">
<!-- process ... -->
</xsl:template>
Upvotes: 0
Reputation: 122364
The current
function doesn't return the path, it returns the current context node (i.e. outside of a []
predicate it's exactly the same as .
, inside a predicate it's the value that .
would be outside it).
Rather than using an <xsl:if>
you should define no-op templates for the same someMode
matching the specific elements you don't want, then the main *
template will only fire for those you do want.
<xsl:template match="foo/bar/baz | foo/bam/baz" mode="someMode" />
<xsl:template match="*" mode="someMode">
<!-- Process here -->
</xsl:template>
You say that
Please note: I can't have other xsl:template elements that specifically match 'foo/bar/baz' and 'foo/bam/baz', as they are being processed in other places (in other ways).
but this is the whole point of modes - existing foo/bar/baz
templates for other modes will still do the same as they used to.
Upvotes: 2