RE: [xsl] node functions

Subject: RE: [xsl] 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/

Current Thread