Home. 
.

transparent

transparent

transparent

Altova Mailing List Archives


Re: [xsl] paras with nested block-level elements to XHTML mix of s and flattened block-level elements

From: Syd Bauman <Syd_Bauman@--------->
To:
Date: 8/1/2008 7:29:00 PM
> My question concerns X/HTML as the transformation target, where "p"
> is the lowest level block-level element, which admits no other
> block-level element(s) as content, but the source is a model (like
> DocBook, TEI, etc.) which allows (and has) a variety of block level
> content in paragraphs.

The following snippets of XSLT 2.0 are what I've been using to
transform <tei:p> elements that contain <tei:list> or <tei:eg> into
XHTML. I do not claim (at all) that this is a good, let alone the
best way to do this, but rather only that it has been working for me.

---------
  <!--
    ** This section contains all the code for moving <list>s and <eg>s that
    ** are nested inside <p>s to being the middle siblings of two <p>s. I.e.:
    ** | <p>Blah-blah-01
    ** |   <eg>exampleA</eg>
    ** |   Blah-blah-02
    ** |   <eg>exampleB</eg>
    ** |   Blah-blah-03</p>
    ** should be transformed into
    ** | <p>Blah-blah-01</p>
    ** | <pre>exampleA</pre>
    ** | <p>Blah-blah-02</p>
    ** | <pre>exampleB</pre>
    ** | <p>Blah-blah-03</p>
    -->
  <xsl:template match="in:p">
    <!-- first handle content up to and including the last <eg> or <list> inside me -->
    <xsl:call-template name="eg-and-list-in-p"/>
    <!-- Note that if there is no <eg> or <list>, the above template did nothing. -->
    <!-- So now we still need to handle the content from the last <eg> or <list> -->
    <!-- (exclusive of it) to the end-of-me, and all my content if there was no -->
    <!-- <eg> or <list>. So the first step is to select all such nodes and tuck 'em -->
    <!-- in a variable. So this XPath selects all nodes that are not <eg> or <list> -->
    <!-- and do not have any <eg> or <list> following. Thus, if there is neither -->
    <!-- an <eg> nor a <list>, it selects all my child nodes. -->
    <xsl:variable name="end-content"
      select="node()[not(self::in:list or self::in:eg) and not(following-sibling::in:list or following-sibling::in:eg)]"/>
    <xsl:if test="$end-content">
      <xsl:element name="p">
        <xsl:apply-templates select="$end-content"/>
      </xsl:element>
    </xsl:if>
  </xsl:template>
  
  <xsl:template name="eg-and-list-in-p">
    <!-- for each of my (this <p>'s) children <eg> or <list> ... -->
    <xsl:for-each select="./in:eg|./in:list">
      <!-- remember the <eg> or <list> before me (now "me" = current <eg> or <list>) -->
      <xsl:variable name="before-me" select="preceding-sibling::node()[self::in:eg or self::in:list][1]"/>
      <!-- 
        ** The content we want is everthing between it (previous <eg> or
        ** <list>, whichever it was) and me (the current <eg> or <list>).
        ** However, don't ask me exactly how this predicate works. While
        ** I understand each little piece, I think, I don't get the big
        ** picture, and I don't understand the detail of why the equality
        ** test could ever fail. It is modified from the incomparable Jeni
        ** Tennison's post to XSL-List of 2001-01-19T15:49Z "How to
        ** transform <BR> to </P><P>"
        ** (http://xslt.com/html/xsl-list/2001-01/msg00927.xhtml),
        ** which I found via Dave Pawson's awesomely helpful FAQ at
        ** http://www.dpawson.co.uk/xsl/index.xhtml
      -->
      <xsl:variable name="content"
        select="preceding-sibling::node()
        [not($before-me) or
        generate-id(preceding-sibling::node()[self::in:eg or self::in:list][1]) =
        generate-id($before-me)]" />
      <!-- if there is any content ... -->
      <xsl:if test="$content">
        <!-- ... put it out in a <p> before we ... -->
        <xsl:element name="p">
          <xsl:apply-templates select="$content"/>
        </xsl:element>
      </xsl:if>
      <!-- ... put current node (and its children) into the output tree. -->
      <xsl:apply-templates select="."/>
    </xsl:for-each>
  </xsl:template>
---------


transparent
Print
Mail
Like It
Disclaimer
.

These Archives are provided for informational purposes only and have been generated directly from the Altova mailing list archive system and are comprised of the lists set forth on www.altova.com/list/index.html. Therefore, Altova does not warrant or guarantee the accuracy, reliability, completeness, usefulness, non-infringement of intellectual property rights, or quality of any content on the Altova Mailing List Archive(s), regardless of who originates that content. You expressly understand and agree that you bear all risks associated with using or relying on that content. Altova will not be liable or responsible in any way for any content posted including, but not limited to, any errors or omissions in content, or for any losses or damage of any kind incurred as a result of the use of or reliance on any content. This disclaimer and limitation on liability is in addition to the disclaimers and limitations contained in the Website Terms of Use and elsewhere on the site.

.
.

transparent

transparent