[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Checking on the existence of tail text?


Subject: Re: [xsl] Checking on the existence of tail text?
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sat, 14 Feb 2009 09:36:36 -0500

At 2009-02-14 11:32 +0100, Petr van Blokland wrote:
I have a question about the check on a node tail text.

I'm suspecting a "proper" solution would have to look at all of your headings at a higher level, rather than at an individual template for sibling headings of different types. Typically when going from a flat vocabulary (like XHTML) to a hierarchical vocabulary (like DocBook), it is more appropriate to use XSLT 2 grouping using group-starting-with=.


But I'll still answer the questions you ask, they just might be the wrong questions.

How can de matching template of <h2> see if there is
nont-whitespace text between </h1> and <h2>, e.g.
the difference between

<h1>Abcd</h1> a text here <h2>Xyz</h2>

<h1>Abcd</h1><!-- no text here --><h2>Xyz</h2>

<xsl:template match="h1"> ... <xsl:if test="following-sibling::node()[1][self::text][normalize-space()] <!--true when the immediately following node is a text node that contains at least one non-white-space character--> </xsl:if> ...

But I don't recommend that below, that just answers your question.

And the extended question, how van the h2-matching
template see the same thing when there is another
tag inbetween that get ignored in the output:

<h1>Abcd</h1> a text here<ignored/> another text here <h2>Xyz</h2>

<h1>Abcd</h1><!-- no text here --><ignored/><!-- no text here --
 ><<h2>Xyz</h2>

Here is where it gets tricky, because you need to limit the search back. And I'm not sure precisely what you are asking for: that the immediately preceding node isn't a white-space-only text node, or *any* node up until the closest <h1>.


I can only really guess what you want below.

This information is needed to know that white space to generate
in output for PDF, where the combination of different heading
must generate different amounts of leading.

Then I think the answer is done at a higher level looking at the combinations, rather than looking from each individual match.


The example below might help you, but it might not ... I hope it does. When you read the instruction name "<xsl:for-each-group>" say to yourself "for the first member of each group". I find this helps me and my students quickly understand what is going on in the loop.

. . . . . . . . . Ken



T:\ftemp>type petr.xml
<all>
<body>
<h1>Abcd</h1> a text here <h2>Xyz</h2>some h2 here
</body>
<body>
<h1>Abcd</h1><!-- no text here --><h2>Xyz</h2>some h2 here
</body>
<body>
<h1>Abcd</h1> a text here<ignored/> another text here <h2>Xyz</h2>some h2 here
</body>
<body>
<h1>Abcd</h1><!-- no text here --><ignored/><!-- no text here --><h2>Xyz</h2>some h2 here
</body>
</all>
T:\ftemp>call xslt2 petr.xml petr.xsl
<?xml version="1.0" encoding="UTF-8"?>


Test 1:
<!--Got some non-white-space text before h2-->
<!--Here's an H2-->


Test 2: <!--Nothing of note before h2--> <!--Here's an H2-->


Test 3: <!--Got some non-white-space text before h2--> <!--Here's an H2-->


Test 4: <!--Nothing of note before h2--> <!--Here's an H2-->


T:\ftemp>type petr.xsl <?xml version="1.0" encoding="US-ASCII"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

<xsl:output indent="yes"/>

<xsl:template match="body">
Test <xsl:number/>:
<xsl:for-each-group select="node()" group-starting-with="h1">
  <!--split body into all of the h1 groups-->
  <xsl:if test="self::h1">
    <!--looking at all of the nodes including and after an h1-->
    <xsl:for-each-group select="current-group()[position()>1]"
                        group-starting-with="h2">
      <!--analyze each h1 group looking for h2-->
      <xsl:choose>
        <xsl:when test="self::h2">
          <xsl:comment>Here's an H2</xsl:comment>
          <xsl:text>&#xa;</xsl:text>
        </xsl:when>
        <xsl:when test="current-group()/self::text()[normalize-space()]">
          <xsl:comment>Got some non-white-space text before h2</xsl:comment>
          <xsl:text>&#xa;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:comment>Nothing of note before h2</xsl:comment>
          <xsl:text>&#xa;</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:if>
</xsl:for-each-group>

</xsl:template>

</xsl:stylesheet>


-- Upcoming hands-on XSLT, UBL & code list hands-on training classes: Brussels, BE 2009-03; Prague, CZ 2009-03, http://www.xmlprague.cz Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video Video lesson: http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18 Video overview: http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18 G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal


Current Thread
Keywords