[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Re: How to match a element + part of an immediate text sibling?


Subject: RE: [xsl] Re: How to match a element + part of an immediate text sibling?
From: "Michael Kay" <mhk@xxxxxxxxx>
Date: Wed, 14 Jan 2004 09:59:47 -0000

> Sorry for the newbie question. I did search the archive, but 
> I guess I just didn't know what keywords to use.
> 
> Say you are doing an HTML-to-HTML transformation and you want 
> to transform: <p> the quick <em>brown</em> fox jumps </p>to: 
> <p> the <em>quick brown fox</em> jumps </p>How would you 
> match the <em> element and the two words immediately 
> surrounding it, so you can rearrange them in the template? Or 
> would you match p[em] instead and then rearrange its children somehow?
> 

Firstly, when the context node is the <em> element, you can get the
adjacent text nodes by using following-sibling::node[1][self::text()]
and preceding-sibling::node()[1][self::text()]. If the <em> element does
not have an adjacent sibling, or if the adjacent sibling is an element
rather than a text node, this will return nothing.

Secondly, there is nothing in XSLT 1.0 that allows you to split a string
into its component words. You can do it yourself using a recursive
template (there are examples in my book XSLT Programmers Reference), or
you can use a vendor- or third-party extension function xx:tokenize(). 

In XSLT 2.0 (actually XPath 2.0) there is a standard function tokenize()
which does the job for you. You can then select the last two words using

tokenize(preceding-sibling::node()[1][self::text()], "\s+")[position() >
last()-2]

Michael Kay



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords