Re: [xsl] From WordprocessingML inline styles to nested inline elements

Subject: Re: [xsl] From WordprocessingML inline styles to nested inline elements
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Wed, 21 Mar 2007 11:56:25 -0400

This is really wicked, but I think you're on the right track.

At 10:19 AM 3/21/2007, you wrote:
I am dealing with a problem that is somehow related to the one that Jeff Sese described in the thread "Transforming a Loose Structure" today, but it is different, so I'm starting a new thread.

Reading up WordprocessingML (from Word 2003), I obtain text runs with inline styles attached as leaf nodes like this:

  <w:t>This is text in bold and italic.</w:t>

In my output, however, the inline styles should nest, and moreover, nest in a particular order:

<run><b><i>This is text in bold and italic.</i></b></run>

As I am generating the stylesheet rather than hand-writing it, I do not want to hardwire the structure of the tree to create, but would like to derive it from a document that only serves the purpose of describing the desired nesting order:


My idea is to generate from this some code that would take the w:r node and translate the run's properties, i.e. the children of w:rPr, into suitably nested elements that are wrapping the contents of w:t.

I am not quite sure which way is the best to tackle the translation part. Maybe hold the structure description in some variable, then work down on the tree it is making up, creating each container element only if there is an instance of the corresponding w:b, w:i etc.? Or recursively call a named template that adds a container for each w:rPr child at the right moment?

Since your style_nesting element holds a representation of the the hierarchy you want to create, it seems that's the sensible tree to traverse in creating your output.

I'm a bit puzzled by your statement that you don't want to "hardwire the structure of the tree to create", since that's exactly what the style_nesting element does (and fairly neatly too). So I'll work out a way of converting your input on the assumption that the style_nesting is available. This is a "meta-stylesheet" kind of application, but not in the sense that it's a stylesheet that generates a stylesheet, but rather only in the sense that its traversal logic is internally configurable rather than being done in the usual way, by traversing the input. (Simply put, you can't do that since there's no mapping of tree to tree.)

You need to parameterize your input to pass it through and work on as you go. Something like this:

<xsl:template match="w:r">
<xsl:apply-templates select="$styles//style-nesting" mode="style">
<xsl:with-param name="r" select="."/>
<!-- initiates traversal of the style-nesting tree, carrying the content -->

<xsl:template match="style-nesting" mode="style"/>
  <!-- simply tunnels (use a better method if available) -->
  <xsl:param name="r"/>
  <xsl:apply-templates mode="style">
    <xsl:with-param name="r" select="$r"/>

<xsl:template match="b | i | u" mode="style">
  <!-- matches elements inside the style nesting tree -->
  <xsl:param name="r"/>
  <xsl:variable name="contents">
    <!-- consolidates generation of the contents of this node
         since it's the same either way -->
    <xsl:apply-templates mode="style">
      <!-- continue down the style nesting tree -->
      <xsl:with-param name="r" select="$r"/>
    <xsl:if test="not(*)">
      <!-- but if we're at the bottom, write our text -->
      <xsl:value-of select="$r/w:t"/>
    <xsl:when test="$r/w:rPr/*[local-name()=local-name(current())]">
      <!-- if parameterized input has our style, we are copied
           (note: you might want a more sophisticated way to map them) -->
        <xsl:copy-of select="$contents"/>
      <!-- even if not, we want our content -->
      <xsl:copy-of select="$contents"/>

Note -- untested!


Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
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