[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: attributes to nested element problem

Subject: Re: attributes to nested element problem
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 19 May 2004 12:38:16 -0400
span align
Tim,

This is pretty heavy stuff. If I had the choice, I'd get the design of the XML changed up front so this wouldn't be necessary. The design of XSLT 1.0 reflects a philosophy that the structure of the result should reflect the structure of the source more or less transparently: strictly speaking you'd have to call this an up-conversion, not what the language was designed for.

But here is an XSLT 1.0 solution. It's heavy because it relies on a recursive template call to build the nested element result tree from the attributes. Note in particular that the template matching "label" has to go to extra trouble to make sure the @paragraph attribute is processed first, and that its contents include nested elements for all the other attributes.

Likewise, the particular nesting you get depends on the order your XSLT processor picks up the other attributes, something which is not specified (since attributes have no order, which is why the extra trouble to get @paragraph first), and which will therefore vary from one processor to another.

On the positive side I think you'll find this is a general solution, though not quite as compact as the XSLT 2.0 solution presented by Mike.

If you need to isolate this code from your default traversal, add a mode to the templates that handle each attribute in turn.

I think the code is as clear as can be, given this is not for the faint of heart. Maybe, if Dimitre were around, he could weigh in on various alternatives here or provide a more elegant solution.

In any case, this does go to show how powerful XSLT 1.0 is (and no, I didn't grow up coding LISP).

Cheers,
Wendell

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

<xsl:template match="label">
<xsl:apply-templates select="@paragraph">
<xsl:with-param name="contents">
<xsl:call-template name="atts-to-elems">
<xsl:with-param name="attributes" select="@*[not(local-name()='paragraph')]"/>
<xsl:with-param name="contents">
<xsl:apply-templates/>
</xsl:with-param>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:template>


<xsl:template name="atts-to-elems">
<xsl:param name="contents"/>
<xsl:param name="attributes" select="false()"/>
<xsl:choose>
<xsl:when test="$attributes">
<xsl:apply-templates select="$attributes[1]">
<xsl:with-param name="contents">
<xsl:call-template name="atts-to-elems">
<xsl:with-param name="attributes" select="$attributes[position() != 1]"/>
<xsl:with-param name="contents" select="$contents"/>
</xsl:call-template>
</xsl:with-param>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$contents"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>


<!-- <label align="left" paragraph="true" italic="true" bold="true">This is a label</label> -->

<xsl:template match="@paragraph[.='true']">
  <xsl:param name="contents"/>
  <para>
    <xsl:copy-of select="$contents"/>
  </para>
</xsl:template>

<xsl:template match="@paragraph">
  <!-- catches labels not marked as @paragraph='true' -->
  <xsl:param name="contents"/>
  <notpara>
    <xsl:copy-of select="$contents"/>
  </notpara>
</xsl:template>

<xsl:template match="@italic[.='true']">
  <xsl:param name="contents"/>
  <i>
    <xsl:copy-of select="$contents"/>
  </i>
</xsl:template>

<xsl:template match="@bold[.='true']">
  <xsl:param name="contents"/>
  <b>
    <xsl:copy-of select="$contents"/>
  </b>
</xsl:template>

<xsl:template match="@align">
  <xsl:param name="contents"/>
  <span align="{.}">
    <xsl:copy-of select="$contents"/>
  </span>
</xsl:template>

<xsl:template match="@*">
  <xsl:param name="contents"/>
  <xsl:copy-of select="$contents"/>
</xsl:template>

</xsl:stylesheet>

At 01:36 AM 5/19/2004, you wrote:
Hi,

I was wondering how to convert an element:

<label align="left" paragraph="true" italic="true" bold="true">This is a label</label>

Into this html:

<p><span align="left"><b><i>This is a label</i></b></span></p>

I found solutions to converting attributes to elements but what about nested elements like this?


======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.