Re: [xsl] Traverse sub tree starting from a particular position

Subject: Re: [xsl] Traverse sub tree starting from a particular position
From: Brandon Ibach <brandon.ibach@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 14 Apr 2011 23:52:34 -0400
Starting with the last <hrdots/> or <hrline/> in the section, add to
it all of its ancestors within the section (those that have the
section as an ancestor).  If any of these have a following sibling
that is an element or a text node consisting of more than just
whitespace, the underline should be output.

  <xsl:template match="section">
    <xsl:variable name="last" select=".//*[self::hrdots |
self::hrline][last()]/ancestor-or-self::*"/>
    <xsl:variable name="in-sect"
select="$last[ancestor::*[generate-id(.) = generate-id(current())]]"/>
    <xsl:variable name="sibs" select="$in-sect/following-sibling::node()"/>
    <xsl:variable name="underline" select="$sibs[self::* |
self::text()[normalize-space(.)]]"/>
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="underline-after">
        <xsl:choose>
          <xsl:when test="$underline">yes</xsl:when>
          <xsl:otherwise>no</xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates select="node()"/>
    </xsl:copy>
  </xsl:template>

-Brandon :)


On Thu, Apr 14, 2011 at 10:32 PM, Graeme Kidd <coolkidd3@xxxxxxxxxxx> wrote:
>
> Hi all,
>
> I am currently converting the following basic XML to FO:
> <root>
>     <section>
>         <hrline /> Some text
>     </section>
>     <section>
>         <hrdots />Some text <hrline />
>     </section>
>     <section>
>        <p> Some Text <hrline /></p>
>     </section>
>     <section>
>         Some Text
>         <hrline />
>         <p>
>             <sub>Some Text <hrdots /></sub>
>         </p>
>         <sub>Some Text</sub>
>     </section>
>     <section>
>         Some Text <hrline />
>        <img src="smile.gif" />
>     </section>
> </root>
>
> In the resulting FO file each "section" element ends with an underline,
however there also elements that produce horizontal lines/dots. The idea is to
try and prevent the "section" underline from appearing when there is no text
or elements after the last hrline/hrdots. This is to prevent double lines from
appearing.
>
> The best I have managed so far is to get the last hrline/hrdots element
within the section:
> <xsl:template match="section">
>     <xsl:variable name="underline">
>         <xsl:choose>
>             <xsl:when test="descendant::node()[self::hrdot or
self::hrline][last()]">
>                 <xsl:text>yes</xsl:text>
>             </xsl:when>
>             <xsl:otherwise>
>                 <xsl:text>no</xsl:text>
>             </xsl:otherwise>
>         </xsl:choose>
>     </xsl:variable>
>      <xsl:copy>
>         <xsl:attribute name="underline-after">
>             <xsl:value-of select="$underline" />
>         </xsl:attribute>
>         <xsl:apply-templates select="node()|@*"/>
>     </xsl:copy>
> </xsl:template>
>
> What I need to next is traverse the rest of the "section" sub tree to detect
whether there is any more text or nodes appearing after that last
hrline/hrdots element. An example of the output should look like this:
>
> <root>
>
>     <section underline-after="yes">
>
>         <hrline /> Some text
>
>     </section>
>
>     <section underline-after="no">
>
>         <hrdots />Some text <hrline />
>
>     </section>
>
>     <section underline-after="no">
>
>        <p> Some Text <hrline /></p>
>
>     </section>
>
>     <section underline-after="yes">
>
>         Some Text
>
>         <hrline />
>
>         <p>
>
>             <sub>Some Text <hrdots /></sub>
>
>         </p>
>
>         <sub>Some Text</sub>
>
>     </section>
>
>     <section underline-after="yes">
>
>         Some Text <hrline />
>
>        <img src="smile.gif" />
>
>     </section>
>
> </root>
>
> Any help or advice would be much appreciated.
>
> Thanks

Current Thread