XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Using XSLT to Fix Swing
by Dave Horlick | Pages: 1, 2, 3

Changing the Document Structure

Next, we'll tweak the stylesheet to target paragraph tags that are immediately preceded by headline tags, and liberate their content.

<?xml version="1.0" encoding="UTF-8" ?>

<!--
Convert XHTML to HTML that will look good when rendered by Java Swing's
JEditorPane component.

The result should not contain the pattern
  <h3>my headline</h3>
  <p>my paragraph</p>
  
Instead, it will have
  <h3>my headline</h3>
  my paragraph
-->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    version="1.0">
    
  <xsl:output method="html" version="3.2" />
  
  <xsl:strip-space elements="*" />
    
  <xsl:template match="xhtml:p">
    <xsl:variable name="previous-node-name" select="name(preceding-sibling::*[1])" />
    <xsl:choose> <!-- To get Swing's JEditorPane to render correctly, we need to
                      remove the paragraph -->
      <xsl:when test="previous-node-name='table'">
        <xsl:apply-templates />
      </xsl:when>
      <xsl:when test="string-length($previous-node-name)=2 and
          substring($previous-node-name,1,1)='h'">
        <xsl:apply-templates />
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="p">
          <xsl:apply-templates />
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
  
  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <!-- go process attributes and children -->
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
  
  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>
  
</xsl:stylesheet>

Save this to a new stylesheet file and try it out. The result should render in Swing without the extraneous line break.

If the prospect of calling this output format "HTML" seems a little perverse to you, feel free to give it a custom file extension such as .swing-html. Swing won't care.

Namespaces

You may have noticed the xhtml: prefix in front of matched element names in our stylesheet. This refers to a namespace defined in the attributes of the stylesheet's root document element. Without this prefix, our stylesheet wouldn't recognize any of the source hypertext markup. The reason for this is that the elements of XHTML, body and table and so on, are considered to reside in a special and lexically distinct land that is unsentimentally called http://www.w3.org/1999/xhtml.

The local-name() function transcribes base element names, but withholds their XHTML namespace from the HTML 3.2 output document. It was the need to filter this namespace that precluded our use of a more common and implicit implementation of the identity transform involving the xsl:copy element. But it's just as well; I find our implementation easier to follow, if a little verbose.

The proper handling of namespaces is probably the trickiest part of XSLT.

Pages: 1, 2, 3

Next Pagearrow