Re: [xsl] Transforming a Loose Structure

Subject: Re: [xsl] Transforming a Loose Structure
From: Jeff Sese <jsese@xxxxxxxxxxxx>
Date: Wed, 21 Mar 2007 16:52:35 +0800
Hi,

I tried this xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; xmlns:xs="http://www.w3.org/2001/XMLSchema"; xmlns:ati="http://www.asiatype.com/ATIFunctions";>
<xsl:template match="section">
<xsl:copy>
<xsl:apply-templates select="par"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="inline">
<xsl:apply-templates select="ati:emphasis-evaluation(attribute::*, node())"/>
</xsl:template>
<xsl:function name="ati:emphasis-evaluation" as="node()*">
<xsl:param name="attributes" as="attribute()*"/>
<xsl:param name="content" as="node()*"/>
<xsl:choose>
<xsl:when test="empty($content/descendant-or-self::text())">
<xsl:copy-of select="$content"/>
</xsl:when>
<xsl:when test="$attributes">
<attr name="{$attributes[1]/name()}" value="{$attributes[1]}">
<xsl:copy-of select="ati:emphasis-evaluation($attributes[position() > 1], $content)"/>
</attr>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$content"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:template match="attr">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="attr[@name='text-underline-style' and @value='solid']">
<emphasis role="underline">
<xsl:apply-templates select="node()"/>
</emphasis>
</xsl:template>
<xsl:template match="attr[@name=('font-style', 'font-variant', 'font-weight') and @value!='normal']">
<emphasis role="{@value}">
<xsl:apply-templates select="node()"/>
</emphasis>
</xsl:template>
<xsl:template match="attr[@name='vertical-align' and @value=('super', 'sub')]">
<xsl:variable name="element.name" select="if (@value='super') then 'superscript' else 'subscript'"/>
<xsl:for-each-group select="node()" group-adjacent="if (self::text()) then 'text' else 'not text'">
<xsl:choose>
<xsl:when test="current-grouping-key() eq 'text'">
<xsl:element name="{if ($element.name='super') then 'superscript' else 'subscript'}">
<xsl:apply-templates select="current-group()"/>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>


into this source xml:

<?xml version="1.0" encoding="UTF-8"?>
<section>
<par>Test para <inline vertical-align="sub">test <inline font-style="italic">para1</inline> and more</inline> Test para</par>
</section>


and got:

<?xml version="1.0" encoding="UTF-8"?>
<section>
<par>Test para <subscript>test </subscript><emphasis role="italic">para1</emphasis><subscript> and more</subscript> Test para</par>
</section>


but my desired output is:

<?xml version="1.0" encoding="UTF-8"?>
<section>
<par>Test para <subscript>test </subscript><emphasis role="italic"><subscript>para1</subscript></emphasis><subscript> and more</subscript> Test para</par>
</section>


I can't find a way to test if the inline[@font-style="italic"] is inside the inline[@vertical-alignment="sub"] in the function that i have used. The function is the one the Mr. Braaksma suggested in my earlier post, which is used to determine the proper emphasis elements to wrap based on the present attributes.

How can i achieve my desired results?

*Jeferson L. Sese*
Asiatype Incorporated
Suite 114, Columbia Tower, Ortigas Ave.,
Greenhills, Mandaluyong City 1550 Philippines


Jeff Sese wrote:
Hi,

I'm trying to transform one xml to another xml, however the elements used for text formatting is much stricter in the output than that of the source. For example:

Source:

<p>Some text <i>some italic text with <b>bold faced</b> and and in <ul>underline</ul></i>.</p>

<i> - for italics
<b> - for bold face
<ul> - for underline
<sup> - superior
<inf> - inferior
<sc> - small-caps

These element can contain each other from the source with no restrictions. However, the output requires that:

<i> - can contain <b>, <ul>, <sup>, <inf>, <sc>
<b> - can contain <i>, <ul>, <sup>, <inf>, <sc>
<ul> - can only contain <i>, <b>
<sup> - can only contain <i>, <b>
<inf> - can only contain <i>, <b>
<sc> - can only contain <i>, <b>

With these restrictions an underlined text in small caps, superior in small caps or underline, inferior in small caps or underline will not have correct counter part from the output, but i think i'll have to default them in someway. But my problem is when the <sup>, <inf>, <ul> or <sc> is inside a <i> or <b>, how can i make my output so that will conform to the restrictions?

TIA!

Current Thread