Subject: Re: [xsl] Deleting following sibling element|
From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx (by way of B. Tommie Usdin)
Date: Thu, 18 Jan 2001 18:27:02 -0500
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> X-Mailer: The Bat! (v1.49) Business Reply-To: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Organization: Jeni Tennison Consulting Ltd X-Priority: 3 (Normal) Message-ID: <10988881044.20010117094336@xxxxxxxxxxxxxxxx> To: Edierley Messias <edierley@xxxxxxxxxxx> CC: xsl-list <xsl-list@xxxxxxxxxxxxxxxxxxxxxx> Subject: Re: [xsl] Deleting following sibling element In-reply-To: <a0500190bb68a9e7f363e@[209\.179\.157\.251]> References: <email@example.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit
Does anybody knows how can I delete an element that is the next following-sibling of the context node?
Rather than thinking of it in terms of 'deleting' an element, think in terms of 'not including' an element. Remember in XSLT you're building a completely new node set - if you don't want something to appear in it, don't put it there :)
For example: [XML] <a href="anything">link</a><br/>
[XSL] <xsl:template match="//a[name(following-sibling::*)='br']"> ???? </xsl:template>
[The XML Output should be] <a href="anything">link</a> ------------------------------------ I'm using the template to copy all nodes and attributes, so the <br/> will also be copied.
I can match the template using the <br/> element because I already wrote another templates thats match the <br/>
There are two ways of not including the output for something in your result - have a template that does nothing when you apply templates to it, or don't apply templates to it in the first place.
Taking the first one first: you need to match the thing that you don't want copied and do nothing with it. In your case, you need to match any 'br' who's immediately preceding sibling is an 'a' element:
[Note - it's better to use self::a rather than comparing the name()s of the nodes because it deals nicely with namespaces.] A template for this would be:
If you have other templates that match br elements, either with predicates like this one or that match brs in context, specifying parents and so on, then you have to assign a higher priority to this template:
<xsl:template match="br[preceding-sibling::*[self::a]]" priority="2" />
You could also cheat and just put it lower down in the stylesheet than the other templates.
Using the other method, not applying templates to it in the first place, is somewhat better in that it stops the processor having to go through the whole 'finding the relevant template' process, which can be time-consuming. How you prevent the template being applied depends on how you're applying the templates. If you're doing it in the normal way (parent to children), then whenever you have a possible parent of one of these br elements, you need to filter them out in the xsl:apply-templates:
<xsl:apply-templates select="*[not(self::br and preceding-sibling::*[self::a])]" />
Of course if you're having to repeat this all over the place, it's just a lot easier to have an empty template act as the filter.
--- Jeni Tennison http://www.jenitennison.com/