Re: [xsl] Denormalizing formatting

Subject: Re: [xsl] Denormalizing formatting
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Mon, 08 Oct 2012 16:23:09 -0400
At 2012-10-08 16:07 -0400, Charles O'Connor wrote:
I am trying to denormalize formatting tags to transform:

<p>Here is some <bold>funky bold text with <italic>some of it also italic and perhaps <underline>underlined</underline>as well.</italic></bold></p>

to:

<p>Here is some <bold>funky bold text with </bold><bold><italic>some of it also italic and perhaps </italic></bold><bold><italic><underline>underlined</underline></italic></bold><bold><italic> well.</italic></bold></p>

How bizarre! I've never seen such a requirement.


The developer I'm working with wants to use string manipulation in .NET, but I'm thinking that XSL would be a more elegant solution.

I totally agree ... dealing with nodes will be far better than dealing with strings.


Can anyone point me to a snippet of code that I could modify to get the desired effect?

I hope the example below helps ... it was an interesting challenge. It produces your output precisely.


I imagine someone has at some time needed to do something similar.

I can't imagine such a transformation at all. Can you shed any light on why the desired output is needed?


. . . . . . . . . Ken

t:\ftemp>type charles.xml
<p>Here is some <bold>funky bold text with <italic>some of it also italic and perhaps <underline>underlined</underline>as well.</italic></bold></p>
t:\ftemp>xslt charles.xml charles.xsl
<?xml version="1.0" encoding="utf-8"?><p>Here is some <bold>funky bold text with </bold><bold><italic>some of it also italic and perhaps </italic></bold><bold><italic><underline>underlined</underline></italic></bold><bold><italic>as well.</italic></bold></p>
t:\ftemp>type charles.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
version="1.0">


<xsl:template match="p">
  <xsl:copy>
    <!--handle all descendent text nodes individually-->
    <xsl:for-each select=".//text()">
      <xsl:call-template name="nest-ancestors">
        <xsl:with-param name="ancestors"
                        select="ancestor::*[ancestor::p]"/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

<!--reconstitute all of the ancestors in order-->
<xsl:template name="nest-ancestors">
  <xsl:param name="ancestors"/>
  <xsl:choose>
    <xsl:when test="$ancestors">
      <!--reconstitute the furthest of the ancestors-->
      <xsl:element name="{name($ancestors[1])}"
                   namespace="{namespace-uri($ancestors[1])}">
        <!--handle the rest of the ancstors-->
        <xsl:call-template name="nest-ancestors">
          <xsl:with-param name="ancestors" select="$ancestors[position()>1]"/>
        </xsl:call-template>
      </xsl:element>
    </xsl:when>
    <xsl:otherwise>
      <!--no more ancestors, so just copy the text node-->
      <xsl:copy/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>

t:\ftemp>






-- Contact us for world-wide XML consulting and instructor-led training Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Google+ profile: https://plus.google.com/116832879756988317389/about Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread