Subject: [xsl] Re: Re: AW: AW: global variable and position() once more From: "Dimitre Novatchev" <dnovatchev@xxxxxxxxx> Date: Tue, 2 Sep 2003 22:20:50 +0200 |
Hi Lizet, The reason for all problems with this source.xml is its very insufficient structure. Therefore, it makes sense to apply a two-step solution, the first step of which produces a new xml document (actually an RTF, which is converted to a document using the ext:node-set() extension function). This new document contains all nodes between two "hr" elements as children of a "section" element. The second pass applies the previous solution and produces the final result. The xsl:key instructions are re-defined to match only text nodes that are children of a "section" with @name having value of "Claims". The complete code now is: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="kSection" match="node()[not(self::hr)]" use="generate-id(preceding-sibling::hr[1])"/> <xsl:key name="kStart" match="section[@name='Claims']/text() [preceding-sibling::*[1][self::br]]" use="contains(., '.') and number(substring-before(., '.')) = number(substring-before(., '.'))"/> <xsl:key name="kTrail" match="section[@name='Claims']/text() [preceding-sibling::*[1][self::br]]" use="generate-id( preceding-sibling::text() [ contains(., '.') and number(substring-before(., '.')) = number(substring-before(., '.')) ] [1] )"/> <xsl:template match="/"> <xsl:variable name="vrtfStructured"> <xsl:for-each select="*/hr"> <section name="{normalize-space(following-sibling::node()[1])}"> <xsl:copy-of select="key('kSection', generate-id())"/> </section> </xsl:for-each> </xsl:variable> <xsl:variable name="vStructured" select="ext:node-set($vrtfStructured)"/> <xsl:for-each select="$vStructured"> <xsl:for-each select="key('kStart', 'true')"> <Claim> <xsl:copy-of select="normalize-space()"/> <xsl:variable name="vLastNumbered" select="position() = last()"/> <xsl:for-each select="key('kTrail', generate-id())"> <xsl:if test="$vLastNumbered or not(position() = last())"> <xsl:copy-of select="concat(substring(.,1,1), normalize-space(substring(.,2)) )"/> </xsl:if> </xsl:for-each> </Claim> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet> When applied on your source.xml: <html> <hr/> Claims <br/> <br/> I claim: <br/> <br/> 1. blah blah <br/> <br/> more blah blah <br/> <br/> 2. blah blah blah <br/> <br/> more blah blah <br/> <br/> 3. blah blah <br/> <br/> more blah blah <br/> <br/> 4. blah blah blah <br/> <br/> more blah blah <br/> <hr/> Description <br/> This is the introduction to the description <br/> 1. blah blah <br/> <br/> more blah blah <br/> <br/> 2. blah blah blah </html> the wanted result is produced: <Claim>1. blah blah more blah blah</Claim> <Claim>2. blah blah blah more blah blah</Claim> <Claim>3. blah blah more blah blah</Claim> <Claim>4. blah blah blah more blah blah</Claim> ===== Cheers, Dimitre Novatchev. http://fxsl.sourceforge.net/ -- the home of FXSL <fe.sola@xxxxxxxxxxxxxx> wrote in message news:1062521638.3f54cb269eb21@xxxxxxxxxxxxxxxxx > Hello Dimitre and all, > The algorithm works very well except for what I mentioned in the previous email and it > was definetely my fault. I have contiguous text nodes with the description that have the > same list structure, so the xhtml looks like this: > > <html> > <hr/> Claims > <br/> > <br/> I claim: > <br/> > <br/> 1. blah blah > <br/> > <br/> more blah blah > <br/> > <br/> 2. blah blah blah > <br/> > <br/> more blah blah > <br/> > <br/> 3. blah blah > <br/> > <br/> more blah blah > <br/> > <br/> 4. blah blah blah > <br/> > <hr/> Description > <br/> This is the introduction to the description > <br/> 1. blah blah > <br/> > <br/> more blah blah > <br/> > <br/> 2. blah blah blah > > </html> > > So far what I have on the xslt is: > <xsl:key name="kStart" > match="text()[preceding-sibling::*[1][self::br]]" > use="contains(., '.') > and > number(substring-before(., '.')) > = > number(substring-before(., '.'))"/> > > <xsl:key name="kTrail" > match="text()[preceding-sibling::*[1][self::br]]" > use="generate-id( > preceding-sibling::text() > [ > contains(., '.') > and > number(substring-before(., '.')) > = > number(substring-before(., '.')) > ] > [1] > )"/> > <xsl:template match="/html/body"> > <xsl:element name="Claims"> > <xsl:apply-templates select="node()[preceding-sibling::text()[starts-with > (normalize-space(.), 'Claims')] and following::text()[starts-with(normalize-space > (.), 'Description')]] " mode="claims"/> > </xsl:element> > </xsl:template> > > <xsl:template match="node()[preceding-sibling::text()[starts-with(normalize-space > (.), 'Claims')] and following::text()[starts-with(normalize-space(.), 'Description')]] " > mode="claims"> > <xsl:for-each select="key('kStart', 'true')"> > <Claim> > <xsl:copy-of select="normalize-space()"/> > <xsl:variable name="vLastNumbered" select="position() = > last()"/> > <xsl:for-each select="key('kTrail', generate-id())"> > > <xsl:if test="$vLastNumbered or not(position() = last > ())"> > > <xsl:copy-of select="concat(substring(.,1,1), > normalize-space(substring(.,2)))"/> > > </xsl:if> > </xsl:for-each> > </Claim> > </xsl:for-each> > </xsl:template> > > > But in the xml output I'm getting the claims alraight except that in the last claim I > get the fisrt text node of the description included and then starts the description > list. I know it has to do with: > node()[preceding-sibling::text()[starts-with(normalize-space(.), 'Claims')] and > following::text()[starts-with(normalize-space(.), 'Description')]] > I thought this expression would select the text nodes between 'Claims' and 'Description' > only so I'm still puzzled why it selects nodes after the 'Description' text node... > Thanks a lot for looking at this, > Lizet > > Mensaje citado por Dimitre Novatchev <dnovatchev@xxxxxxxxx>: > > > > > > Here's the corrected code (the key definitions are omitted as they are the > > same: > > > > <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="kStart" > > match="text()[preceding-sibling::*[1][self::br]]" > > use="contains(., '.') > > and > > number(substring-before(., '.')) > > = > > number(substring-before(., '.'))"/> > > > > <xsl:key name="kTrail" > > match="text()[preceding-sibling::*[1][self::br]]" > > use="generate-id( > > preceding-sibling::text() > > [ > > contains(., '.') > > and > > number(substring-before(., '.')) > > = > > number(substring-before(., '.')) > > ] > > [1] > > )"/> > > > > <xsl:template match="/"> > > <xsl:for-each select="key('kStart', 'true')"> > > <Claim> > > <xsl:copy-of select="normalize-space()"/> > > <xsl:variable name="vLastNumbered" select="position() = last()"/> > > <xsl:for-each select="key('kTrail', generate-id())"> > > <xsl:if test="$vLastNumbered or not(position() = last())"> > > <xsl:copy-of > > select="concat(substring(.,1,1), > > normalize-space(substring(.,2)) > > )"/> > > </xsl:if> > > </xsl:for-each> > > </Claim> > > </xsl:for-each> > > </xsl:template> > > </xsl:stylesheet> > > > > I believe that two very good books on XSLT are the following: > > > > "Beginning XSLT" by Jeni Tennison > > > > "XSLT Programmer's Reference" by Michael Kay. > > > > > > > > > > > > > > > > > > > > ===== > > Cheers, > > > > Dimitre Novatchev. > > http://fxsl.sourceforge.net/ -- the home of FXSL > > > > __________________________________ > > Do you Yahoo!? > > Yahoo! SiteBuilder - Free, easy-to-use web site design software > > http://sitebuilder.yahoo.com > > > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > > > > > > > ------------------------------------------------- > Este mensaje fue enviado usando el servicio de correo en web de Infomed > http://webmail.sld.cu > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list > > XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Re: AW: AW: global variab, fe . sola | Thread | Re: [xsl] Re: Re: AW: AW: global va, fe . sola |
Re: [xsl] Re: Re: AW: AW: global va, fe . sola | Date | Re: [xsl] Re: Re: AW: AW: global va, fe . sola |
Month |