|
Subject: Re: [xsl] Fwd: text nodes From: "Lucas Lain" <lucas.lain@xxxxxxxxx> Date: Thu, 18 Sep 2008 16:59:14 -0300 |
Hello Wendell,
first of all, thank you for your response.
Second:
THANK YOU FOR YOUR RESPONSE! =)
you read my mind. Everything is working great right now!
Regards,
Lucas.
On Thu, Sep 18, 2008 at 11:26 AM, Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> wrote:
> Lucas,
>
> The problem you are looking at is actually a variant of a grouping problem.
> Processing all the nodes up to a particular node amounts to grouping the
> nodes into several "before" and "after" groups.
>
> Grouping in general, and this sort of grouping in particular (called
> "positional grouping") are a well-known weak spot in XSLT 1.0. Accordingly,
> if you can use XSLT 2.0, you will have much better and much easier solutions
> available.
>
> If you must use XSLT 1.0, however, there are known methods. The two best
> methods are probably sibling recursion and key-based association. In sibling
> recursion, basically what you do is shift your processor (using template
> modes for this) out of its normal pattern of selecting and processing
> (applying templates) all children, and instead process only the first child,
> which processes the next, which processes the next, etc. This gives you a
> way to introduce stop and restart conditions into the processing.
>
> In key-based association, you basically associate the nodes, typically using
> a key (this makes it easier), with the node you want to stop on, and then
> use the key to retrieve them. This is essentially an optimization of the
> method that Sam has suggested (his logic does the same thing without the
> key).
>
> I think this method may be slightly easier for you. It would look something
> like:
>
> (Sam's code, for comparison)
>>
>> <xsl:template match="a">
>> <xsl:variable name="next_a"
>> select="generate-id(following-sibling::a[1])"/>
>>
>> <xsl:for-each select="following-sibling::text()[ generate-id(
>> following-sibling::a[1] ) = $next_a ]">
>> <xsl:value-of select="."/>
>> </xsl:for-each>
>>
>> </xsl:template>
>>
>> <xsl:template match="some_element">
>> <xsl:apply-templates select="a"/>
>> </xsl:template>
>
> <xsl:key name="nodes-by-last-stop" match="node()"
> use="generate-id(preceding-sibling::a|parent::*)[last()])"/>
> <!-- using this key, each node in the document can be retrieved using
> the system-generated ID of the last preceding sibling 'a'
> element, or of its parent (for those that have no
> preceding-sibling::a) -->
>
> <xsl:template match="a">
> <!-- when 'a' is matched, nothing is done with it, but the elements
> associated by the key with its generated ID are processed -->
> <xsl:apply-templates select="key('nodes-by-last-stop',generate-id())"/>
> </xsl:template>
>
> <xsl:template match="some_element">
> <!-- when an element requiring splitting is matched, its own associated
> elements are processed (these are children that have no 'a' preceding
> them), then its 'a' children are processed -->
> <xsl:apply-templates select="key('nodes-by-last-stop',generate-id()"/>
> <xsl:apply-templates select="a"/>
> </xsl:template>
>
> If you research how keys work, you will find this does exactly the same
> thing as Sam's logic, only more concisely and more comprehensively (since it
> doesn't drop elements before the first 'a').
>
> This can be extended to include 'lb' elements among the "stop" elements as
> follows:
>
> <xsl:key name="nodes-by-last-stop" match="node()"
> use="generate-id(parent::*|preceding-sibling::a|preceding-sibling::lb)[last()])"/>
>
> <xsl:template match="a | lb">
> <xsl:apply-templates select="key('nodes-by-last-stop',generate-id())"/>
> </xsl:template>
>
> <xsl:template match="some_element">
> <xsl:apply-templates select="key('nodes-by-last-stop',generate-id()"/>
> <xsl:apply-templates select="a | lb"/>
> </xsl:template>
>
> Note: this code is untested, although the algorithm isn't.
>
> Good luck (and find a way to use XSLT 2.0!),
> Wendell
>
> At 07:35 AM 9/18/2008, you wrote:
>>
>> Thank you Sam!
>>
>> i meant by ' stop on the first occurrence on the "[ ]" ' this:
>>
>> for this input:
>>
>> <some_element>
>> <a>hello</a> some text 1<br/>
>> some text 2
>> some text 3
>> <a>hello 2</a> some text 4
>> some text 5
>> some text 6
>> > </some_element>
>>
>> i want this output:
>>
>> "some text 1 some text 2 some text 3" and
>> "some text 4 some text 5 some text 6"
>>
>> I am not sure how to deal with <br/> elements. I'm using xsl to
>> extract data from HTML.
>> i can't make the xsl you sent me to work. If this info helps you to
>> help me ... let me know.
>>
>> best regards!
>>
>> L.
>>
>> On Wed, Sep 17, 2008 at 10:52 AM, Sam Byland <shbyland@xxxxxxxxxxx> wrote:
>> >> the output is:
>> >>
>> >> "some text 1 some text 2 some text 3"
>> >
>> > Lucas,
>> >
>> > I used:
>> >
>> > <some_element>
>> > <a>hello</a> some text 1<br/>
>> > some text 2
>> > some text 3
>> > <a>hello 2</a>
>> > </some_element>
>> >
>> > for the input. Assuming you only want to output the text up to the next
>> > <a>
>> > element, then something like this (XSLT1.0) might get you in the right
>> > direction:
>> >
>> > <xsl:template match="a">
>> >
>> > <xsl:variable name="next_a"
>> > select="generate-id(following-sibling::a[1])"/>
>> >
>> > <xsl:for-each select="following-sibling::text()[ generate-id(
>> > following-sibling::a[1] ) = $next_a ]">
>> > <xsl:value-of select="."/>
>> > </xsl:for-each>
>> >
>> > </xsl:template>
>> >
>> > <xsl:template match="some_element">
>> > <xsl:apply-templates select="a"/>
>> > </xsl:template>
>> >
>> > I'm not totally sure what you meant by ' stop on the first occurrence on
>> > the
>> > "[ ]" '
>> >
>> > ...sam
>> >
>
>
> ======================================================================
> Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx
> Mulberry Technologies, Inc. http://www.mulberrytech.com
> 17 West Jefferson Street Direct Phone: 301/315-9635
> Suite 207 Phone: 301/315-9631
> Rockville, MD 20850 Fax: 301/315-8285
> ----------------------------------------------------------------------
> Mulberry Technologies: A Consultancy Specializing in SGML and XML
> ======================================================================
>
>
--
Ing. Lucas Lain
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| Re: [xsl] Fwd: text nodes, Wendell Piez | Thread | [xsl] Distinct values with XPath qu, Matthew Hailstone |
| Re: [xsl] Fundimentle Predicate Pro, David Carlisle | Date | Re: [xsl] // expanding to descendan, Evan Lenz |
| Month |