Re: [xsl] Conditional text using attributes

Subject: Re: [xsl] Conditional text using attributes
From: "Steve Muench" <Steve.Muench@xxxxxxxxxx>
Date: Thu, 28 Dec 2000 17:40:31 -0800
| I think the inner workings of the DocBook stylesheets are such that
| your example transform will perform as expected for conditionally
| including some elements, but not for others -- for example:
| 
|   <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|     "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd";>
|   <article>
|     <articleinfo>
|       <title os="PC">Starting the timer using Microsoft Windows</title>
|       <title os="Mac">Starting the timer using MacOS</title>
|     </articleinfo>
|     <para>Press the...</para>
|   </article>

I'm sure that there are some cases that would be more finessing,
but by augmenting my base "norm.xsl" stylesheet to be:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">
  <xsl:strip-space elements="*"/>
  <xsl:preserve-space elements="programlisting"/>

  <xsl:template match="book|article">
   <html>
     <body>
      <xsl:apply-templates/>
     </body>
   </html>
  </xsl:template>

  <xsl:template match="articleinfo">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="articleinfo/title">
    <h1><xsl:apply-templates/></h1>
  </xsl:template>

  <xsl:template match="para">
    <p><xsl:apply-templates/></p>
  </xsl:template>

  <xsl:template match="emphasis">
    <i><xsl:apply-templates/></i>
  </xsl:template>

</xsl:stylesheet>

Then when I use my "beth.xsl" stylesheet I get the expected
results like:

 $ oraxsl test2.xml beth.xsl

<html>
   <body>
      <h1>Starting the timer using MacOS</h1>
      <p>
      Press the  mouse button to start
      the timer. You can use the <i>Finder</i> to launch a new program.
    </p>
   </body>
</html>


 $ oraxsl -p os='PC' test2.xml beth.xsl

<html>
   <body>
      <h1>Starting the timer using Microsoft Windows</h1>
      <p>
      Press the <i>Left</i> mouse button to start
      the timer. You can use the <i>Start Button</i> to launch a new program.
    </p>
   </body>
</html>

I still don't doubt you that the full-fledged DocBook stylesheets
might present some more surprises...

| So instead of importing the DocBook templates, might it be possible
| instead to write a straight XML to XML "conditional inclusion"
| transform that will work with *any* well-formed XML document instance?
| 
| What I mean specifically is a transform that:
| 
|   * conditionally includes elements based simply on attribute
|     names/values, without regard at all for the actual element names
| 
|   * is a "standalone" transform that doesn't rely on importing other
|     stylesheets that contain templates matching the element names
| 
| Is that possible? How could it be expressed in XSLT?

The following stylesheet augments the identity transformation
with a template that suppresses copying to the result any
element which *HAS* an "os" attribute whose value is *different*
from the current top-level os parameter value.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"; version="1.0">

  <xsl:param name="os">Mac</xsl:param>

  <!-- Identity Transformation -->
  <xsl:template match="node()|@*">
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  </xsl:template>

  <!-- 
   | If element HAS an os attribute and its value is NOT
   | what we're looking for, then squelch it
   +-->
  <xsl:template match="*[@os and @os!=$os]"/>

</xsl:stylesheet>

$ oraxsl test2.xml cond.xsl

Produces:

<?xml version = '1.0' encoding = 'UTF-8'?>
<article>
    <articleinfo>

      <title os="Mac">Starting the timer using MacOS</title>
    </articleinfo>
    <para>
      Press the  mouse button to start
      the timer. You can use the <emphasis os="Mac">Finder</emphasis>
       to launch a new program.
    </para>
  </article>

$ oraxsl -p os='PC' test2.xml cond.xsl

Produces:

<?xml version = '1.0' encoding = 'UTF-8'?>
<article>
    <articleinfo>
      <title os="PC">Starting the timer using Microsoft Windows</title>

    </articleinfo>
    <para>
      Press the <emphasis os="PC">Left</emphasis> mouse button to start
      the timer. You can use the
      <emphasis os="PC">Start Button</emphasis> to launch a new program.
    </para>
  </article>

This assumes that if an element has os="Mac" -- and the
current value of the $os param = "PC" -- that you want
that element AND ALL OF ITS CONTENT to be squelched along
with it.
______________________________________________________________
Steve Muench, Lead XML Evangelist & Consulting Product Manager
BC4J & XSQL Servlet Development Teams, Oracle Rep to XSL WG
Author "Building Oracle XML Applications", O'Reilly
http://www.oreilly.com/catalog/orxmlapp/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread