Re: [xsl] How To Map From Hierarchy to Wrapped Text Sequences?

Subject: Re: [xsl] How To Map From Hierarchy to Wrapped Text Sequences?
From: Tony Graham <Tony.Graham@xxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 10 Apr 2008 17:47:01 +0100
On Thu, Apr 10 2008 15:42:36 +0100, ekimber@xxxxxxxxxxxx wrote:
> I am working on generating Adobe InCopy article (INCX) files from DITA
> source. The challenge I face is that the DITA source is typical
> documentation XML, where you have mixed content with embedded inline
> elements that may be nested to any depth, e.g.:
>
> <p>Some text <i>italic text <b>now bold italic</b> back to italic</i>
> more text</p>
>
> In the INCX representation of this, each text string with distinct
> formatting is separately wrapped as a "text run", making the above
> into:
>
> <txsr><pcnt>Some text </pcnt></txsr>
> <txsr><pcnt>italic text </pcnt></txsr>
> <txsr><pcnt>now bold italic</pcnt></txsr>
> <txsr><pcnt> back to italic</pcnt></txsr>
> <txsr><pcnt> more text& #x0a;</pcnt></txsr>

Here's two one-pass solutions that differ in where you put the style
selection.

The second approach is messier, but it does let you pass the style
information as a parameter (or more than one parameter if you wanted).

You could combine the approaches and build up a sequence as the
parameter value (e.g., "('bold', 'italic')") and then let the template
for text() decide what to do based on what's in the sequence.

Regards,


Tony Graham                         Tony.Graham@xxxxxxxxxxxxxxxxxxxxxx
Director                                  W3C XSL FO SG Invited Expert
Menteith Consulting Ltd
XML, XSL and XSLT consulting, programming and training
Registered Office: 13 Kelly's Bay Beach, Skerries, Co. Dublin, Ireland
Registered in Ireland - No. 428599   http://www.menteithconsulting.com
  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
xmlroff XSL Formatter                               http://xmlroff.org
xslide Emacs mode                  http://www.menteith.com/wiki/xslide
Unicode: A Primer                               urn:isbn:0-7645-4625-2


------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

  <xsl:output method="xml"/>

  <xsl:template match="p">
    <xsl:for-each select=".//text()">
      <txsr>
        <xsl:attribute name="style">
          <xsl:choose>
            <xsl:when test="ancestor::b and ancestor::i">
              <xsl:text>bold-italic</xsl:text>
            </xsl:when>
            <xsl:when test="ancestor::b">
              <xsl:text>bold</xsl:text>
            </xsl:when>
            <xsl:when test="ancestor::i">
              <xsl:text>italic</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>default</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
        <xcnt>
          <xsl:value-of select="translate(., '&#x0A;', ' ')"/>
          <xsl:if test="position() = last()">
            <xsl:text>&#x0A;</xsl:text>
          </xsl:if>
        </xcnt>
      </txsr>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>
------------------------------------------------------------

------------------------------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  xmlns:xs="http://www.w3.org/2001/XMLSchema";
  exclude-result-prefixes="xs"
  version="2.0">

  <xsl:output method="xml"/>

  <xsl:strip-space elements="test"/>
  
  <xsl:template match="p">
    <xsl:apply-templates>
      <xsl:with-param name="style" select="'default'"/>
    </xsl:apply-templates>
  </xsl:template>
  
  <xsl:template match="text()">
    <xsl:param name="style" as="xs:string" required="yes"/>
    <txsr style="{$style}">
      <xcnt>
        <xsl:value-of select="translate(., '&#x0A;', ' ')"/>
        <xsl:if test="not(exists(following::text()[1])) or
          (exists(following::p[1]) and
          not(following::text()[1] &lt;&lt; following::p[1]))">
          <xsl:text>&#x0A;</xsl:text>
        </xsl:if>
      </xcnt>
    </txsr>
  </xsl:template>
  
  <xsl:template match="b">
    <xsl:param name="style" as="xs:string" required="yes"/>
    
    <xsl:variable name="new-style">
      <xsl:choose>
        <xsl:when test="$style = 'italic'">
          <xsl:text>bold-italic</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>bold</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    
    <xsl:apply-templates>
      <xsl:with-param name="style" select="$new-style"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="i">
    <xsl:param name="style" as="xs:string" required="yes"/>
    
    <xsl:variable name="new-style">
      <xsl:choose>
        <xsl:when test="$style = 'bold'">
          <xsl:text>bold-italic</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>italic</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    
    <xsl:apply-templates>
      <xsl:with-param name="style" select="$new-style"/>
    </xsl:apply-templates>
  </xsl:template>

</xsl:stylesheet>
------------------------------------------------------------

Current Thread