Subject: RE: node functions
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Tue, 5 Aug 2008 16:20:00 +0100
|
> file2.xml
> <test2>
> <info>
> <requirement>
> <level1>
> <para></para>
> <pub></pub>
> </level1>
> </requirement>
> </info>
> </test2>
>
>
> So, info and pub are two common elements between there two
> xml files. So there is a common style sheet just for pub
> called pub.xsl. pub has an attribute level which can be set to 1~4.
> But in one commong style sheet, I want to apply templates for
> all //info elements and not include //pub elements which have
> @level='1'
Your source document doesn't have any attributes on pub elements: but it
does have an element called level1 which is the parent of the pub element.
Are you confused, or are you just trying to confuse the rest of us?
>
> I tried:
>
> <xsl:choose>
> <xsl:when test="//info(not[self::pub[@level='1']">
>
> <xsl:apply-templates select="//info(not[self::pub[@level='1']">
> </xsl:when>
> </xsl:choose>
>
> This is obv wrong because the processor complains about it.
1. not() is a function call, therefore it requires round brackets ()
2. a filter predicate is always written in square brackets.
3. both kinds of brackets have to match up!
So that corrects the grammar to:
//info[not(self::pub[@level='1'])]
4. An info element will never be a pub element, so you don't want the self::
axis here, you want some other axis. In your example pub is nested several
layers below info - but that pub element doesn't have a level attribute, so
perhaps your source document isn't useful as a guide.
5. If the select attribute of apply-templates doesn't select anything, then
it does nothing, so you don't need to test it first in an xsl:if or
xsl:choose.
6. You might be better off applying templates to all the elements, and
having different template rules to process those with level="1" and those
with a different level.
Michael Kay
http://www.saxonica.com/
|