[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message] Re: <br/> to <p> and optimization
Keys can be used for improved efficiency. The following defines a key that will select all following siblings of a "br" element, that must be wrapped within a "p": <xsl:key name="kbrScope" match="*" use="generate-id(preceding-sibling::br[1])"/> In a positional grouping problem it is often the case that we want to have full control over the sequence of processing and it is very useful to traverse and transform the source xml document one node at a time in document order. Here's the full transformation. Note that we successfully handle nested pairs of <br/> elements. Note also the "node-at-a-time" version of the identity template: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="kbrScope" match="*" use="generate-id(preceding-sibling::br[1])"/> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="node()[1]"/> </xsl:copy> <xsl:apply-templates select="following-sibling::node()[1]"/> </xsl:template> <!-- The following is just individual copy with wrapping without propagating the transformation to the following sibling --> <xsl:template match="@* | node()" mode="inPara"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="node()[1]"/> </xsl:copy> </xsl:template> <xsl:template match="br"> <p> <xsl:apply-templates mode="inPara" select="key('kbrScope', generate-id())[not(self::br)]"/> </p> <xsl:apply-templates select="following-sibling::br[1]/following-sibling::node()[1]"/> </xsl:template> </xsl:stylesheet> When applied on this source.xml: <t> <a> <br/> <b> <e/> </b> <c> <br/> <f/> <g/> <br/> </c> </a> </t> the wanted result is produced: <t> <a> <p> <b> <e/> </b> <c> <p> <f/> <g/> </p> </c> </p> </a> </t> ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL "Emmanuel Bégué" <emmanuel@xxxxxxxxxxxxx> wrote in message news:NBBBJDMNAJNNCLEBLPCKAEDEFPAA.emmanuel@xxxxxxxxxxxxxxxx Hello, On the archives of this list I have found a solution to the problem of putting all elements between two <br/> elements into a <p> element: http://www.biglist.com/lists/xsl-list/archives/200101/msg00865.html However, this process takes a very very long time for "big" files (over 100k) which have lots of brs (up to two minutes), and I am looking for a way to optimize it. In fact my problem is I'm not sure I correctly understand the following line: <xsl:variable name="content" select="preceding-sibling::node() [not($br-before) or generate-id(preceding-sibling::br[1]) = generate-id($br-before)]" /> $br-before is the preceding <br/>: <xsl:variable name="br-before" select="preceding-sibling::br[1]" /> So, for setting $content, do we mean that we test _all_ nodes before the current <br/>, and for each of them we test that they are not themselves the preceding <br/> (not($br-before)) and that they are actually after the same <br/> than the one located by $br-before? In that case obviously we test the same nodes many times: for every new <br/>, we want to add nodes that are before the current <br/> and after the preceding one, but we test again the nodes that are before the last <br/> up to the start of the containing element. Therefore what we need is a way to "stop" the selection once the current node that is being tested is in fact $br-before? Is this correct? Regards, Emmanuel Bégué XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|