[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XSL pattern needed for begin/end elements

Subject: Re: XSL pattern needed for begin/end elements
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Wed, 07 Jul 2004 16:33:13 -0600
hyperlink xsl
Tracy,

I am soooo sorry this took so long but my day has been bouncing back and forth and every time I would get a chance to sit down and write this something else would come along... Anyway, I finally got ten minutes to get this written out real quick... The key is to use generate-id() against hyperlink_end in the first position that follows the current hyperlink_begin. By creating a variable that holds the value of the generate-id() process we can then check to make sure that as we are processing the run_text elements that they dont have a preceding-sibling that generates the same id that is stored in our variable. So this:

<xsl:template match="/">
  <xsl:apply-templates select="doc/hyperlink_begin"/>
</xsl:template>

<xsl:template match="hyperlink_begin">
<xsl:variable name="count" select="generate-id(following-sibling::hyperlink_end[1])"/>
<cod>
  <Hyperlink>
    <xsl:attribute name="xLink:href"><xsl:value-of select="concat(locator_url/@protocol, '://', locator_url/@host_name)"/></xsl:attribute>
    <xsl:apply-templates select="following-sibling::text_run[not(generate-id(preceding-sibling::hyperlink_end) = $count)]"/>
  </Hyperlink>
</cod>
</xsl:template>

<xsl:template match="text_run[@emphasis]">
  <b><xsl:value-of select="."/></b>
</xsl:template>

<xsl:template match="text_run">
  <xsl:value-of select="."/>
</xsl:template>

Will produce the output you want by ensuring that the only text_run elements that are processed are sandwiched between the current hyperlink_begin and the hyperlink_end in the first position after the current context. Does that make sense?

So this XML:

  <doc>
    <hyperlink_begin id="111" end="222">
      <locator_url protocol="http" host_name="www.sf.net"/>
    </hyperlink_begin>
    <text_run>Click</text_run>
     <text_run emphasis="bold">here One.</text_run>
    <hyperlink_end id="222" begin="111"/>
    <hyperlink_begin id="111" end="222">
      <locator_url protocol="http" host_name="www.sf.net"/>
    </hyperlink_begin>
    <text_run>Click</text_run>
     <text_run emphasis="bold">here Two.</text_run>
    <hyperlink_end id="222" begin="111"/>
  </doc>

Gets processed and output as such:

<?xml version="1.0" encoding="UTF-8"?>
<cod>
  <Hyperlink xLink:href="http://www.sf.net">Click<b>here One.</b>
  </Hyperlink>
</cod>
<cod>
  <Hyperlink xLink:href="http://www.sf.net">Click<b>here Two.</b>
  </Hyperlink>
</cod>

And im pretty sure thats what you wanted?

Hope this helped!

Regards,

<M:D/>

Tracy Atteberry wrote:
Sorry about that.  Looks like my client was inserting '3D's after every
'='.  Let's try again...

---------------
Hi all,

I'm looking for an XSL pattern to solve the problem of going from XML
that has separate begin and end elements to one that does not.

Please, please note that I do not control either the source or target
XML formats.  If I did, this would be much easier.

Source XML snip:

<doc>
  <hyperlink_begin id="111" end="222">
    <locator_url protocol="http" host_name="www.sf.net"/>
  </hyperlink_begin>
  <text_run>Click</text_run>
  <text_run emphasis="bold">here.</text_run>
  <hyperlink_end id="222" begin="111"/>
</doc>

Target XML example:

<cod>
  <HyperLink xlink:href="http://www.sf.net">
    Click <b>here.</b>
  </HyperLink>
</cod>

In my case I can assume that associated begin and end hyperlink tags
will occur as siblings -- though generally this is not the case and in
fact, this is the reason the begin and end tags are unique elements.

I have a template that /almost/ works so feel free to let me know why it
fails OR suggest a completely different solution.

Current XSL template snip:

<xsl:template match="//hyperlink_begin">
    <xsl:variable name="linkUrl">
        <xsl:value-of select="locator_url/@protocol"/>
        <xsl:text>://</xsl:text>
        <xsl:value-of select="locator_url/@host_name"/>
    </xsl:variable>
    <xsl:variable name="endID" select="@end"/>
    <xsl:element name="HyperLink">
        <xsl:attribute name="xlink:href"><xsl:value-of
select="$linkUrl"/></xsl:attribute>
        <xsl:apply-templates select="(following-sibling::*) except
(following-sibling::hyperlink_end[@id=$endID]/following-sibling::*)"/>
    </xsl:element>
</xsl:template>

This produces the correct hyperlink but the template for text_run
elements gets called twice this way -- once inside the hyperlink, then
again as templates continue to be applied.

Any help would be greatly appreciated. Thanks!

Tracy Atteberry

PS. I'm using Saxon 8



--+------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe@xxxxxxxxxxxxxxxxxxxxxx>
--+--


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.