This transformation:
<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:for-each select="key('kTrail', generate-id())">
<xsl:if test="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>
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/>
<hr/> Description
<br/>
</html>
produces the wanted result:
<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</Claim>
=====
Cheers,
Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL
<fe(_dot_)sola(_at_)infomed(_dot_)sld(_dot_)cu> wrote in message
news:1062365071(_dot_)3f52678f72c4f(_at_)webmail(_dot_)sld(_dot_)cu(_dot_)(_dot_)(_dot_)
Hi Markus and all,
Yep, that template worked fine, now I have a different problem and have
been reading the
threads of "Incrementing Global variables"... The thing is I have to
select each claim
on the document and enclose it in <claim></claim>
The input xhtml file looks like this:
<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/>
and I need an xml output:
<Claims>
<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 </Claim>
</Claims>
The number of claims varies from document to document. I thought about
removing the
<br/> tags with regexps to make things easier...
What I have so far:
<xsl:template
match="preceding-sibling::text()[starts-with(normalize-space
(.), 'Claims')]
and following::text()[starts-with(normalize-space(.), 'Description']">
<xsl:variable name="counter">0</xsl:variable>
<xsl:for-each
select="following-sibling::text()[starts-with
(normalized-space(.),'$counter+1')]">
<Claim>
<xsl:value-of
select="normalize-space(.)"/>
</Claim>
</xsl:for-each>
</xsl:template>
But it gives me error with the Xpath expression due to the variable
increment, what
should I use, a parameter?
tia,
lizet
Mensaje citado por Markus Abt <abt(_at_)comet(_dot_)de>:
Hi Lizet,
you can use a similar Xpath to check the following sibling axis for
checking the end condition and combining the two with "and":
<xsl:apply-templates select="html/body/node()[
preceding-sibling::text()[starts-with(normalize-space(.),
'References')]
and following-sibling::text()[starts-with(normalize-space(.),
'Description')]]"/>
Cheers,
Markus
__________________________
Markus Abt
Comet Computer GmbH
http://www.comet.de
----------
Von: fe(_dot_)sola(_at_)infomed(_dot_)sld(_dot_)cu
Gesendet: Donnerstag, 28. August 2003 23:02
An: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Betreff: Re: AW: [xsl] global variable and position() once more
Hi Markus,
It worked fine, thanks. Now I'm doing a similar thing but taking the
text nodes between
a text node that starts with 'References' and the text node with
'Description', but
it's
a similar template...
again thanks,
lizet
Mensaje citado por Markus Abt <abt(_at_)comet(_dot_)de>:
Hi,
if you want output everything after the "Description" text node, try
this:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Document>
<!-- select all nodes after the Description text node -->
<xsl:apply-templates
select="html/body/node()[preceding-sibling::text()[starts-with(normalize-spa
ce(.),
'Description')]]"/>
</Document>
</xsl:template>
<!-- copy all nodes with their descendants. Adjust to your needs -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The Xpath works as follows:
- html/body/node() selects all child nodes of the body element.
- [ ... ] gives a condition to the previous selection.
It is tested for every selected node.
- preceding-sibling::text() selects all preceding siblings (for every
selected
node
above).
- starts-with(normalize-space(.), 'Description') tests for the
"Description" text
node.
It is tested for every preceding sibling.
- So, preceding-sibling::text()[starts-with(normalize-space(.),
'Description')]
selects only this node.
- If there is such a preceding sibling, the outer condition ([...])
is true.
- The result is, only the html/body/node() with this condition true
are selected.
- apply-templates then processes this nodes.
The second template just copies everythig through, discard it, if you
have
your own templates to handle further processing.
Hope this helps,
Markus
__________________________
Markus Abt
Comet Computer GmbH
http://www.comet.de
----------
Von: fe(_dot_)sola(_at_)infomed(_dot_)sld(_dot_)cu
Gesendet: Donnerstag, 28. August 2003 17:53
An: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Betreff: RE: [xsl] global variable and position() once more
Hello, being a newbie is a pain...
I decided to try Michael Kay's suggestion of using a global variable.
My problem is
that
I need to select the text nodes after a text node that starts with the
word 'Description'.
The xhtml looks more or less like this: (This is a simplified sample
version, could
provide the real one on request)
<html>
<head>
<!--Something here-->
<head>
<body>
blah bla blah
<table>
<!-- something here-->
</table>
Description
<table>
<!-- something here-->
</table>
text nodes to select with the description text
</body>
</html>
My xsl stylesheet looks like this:
..
<xsl:template match="/">
...
<Document>
<xsl:apply-templates select="html"/>
</Document>
...
</xsl:template>
..
<xsl:variable name="descPos"
select="//text()[starts-with(normalize-space
(),'Description')]"/>
..
<xsl:template match="html">
<xsl:element name="description">
<xsl:apply-templates
select="text()[position()>$descPos]"/>
</xsl:element>
..
</xsl:template>
..
I can't manage to store in the descPos global variable the position of
the node that
starts with 'Description', when I try
select="//text()[starts-with(normalize-space
(),'Description')position()] or try to get the position function
somewhere in that
XPath
expression I get errors.
So far the descPos variable gets a wrong value, always 1 and the
mentioned text
node
has
a position 30 or more on some other input documents.
thanks a lot for looking at this,
Lizet
-------------------------------------------------
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
-------------------------------------------------
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
-------------------------------------------------
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