Re: [xsl] searching and replacing

Subject: Re: [xsl] searching and replacing
From: Mike Brown <mike@xxxxxxxx>
Date: Fri, 31 May 2002 01:30:32 -0600 (MDT)
normbishop1@xxxxxxxxxxxx wrote:
> I have written a template to search for any string containing <sub> or <sup> and to do subscript and superscript accordingly.  The template works fine (I think)...

Yiks. You have many problems in the stylesheet you posted.
You apparently...

1. think that there is no difference between the literal text-and-markup of
the document and the XPath/XSLT node tree that is implied by it;

2. are trying to produce an exact copy of your input. That is,
<sub>foo</sub> in becomes <sub>foo</sub> out;

3. think the match pattern in a template causes nodes to be processed, rather
than just designating the template as being eligible to process a node that
matches the given pattern, *if* such a node happens to be selected for
processing via xsl:apply-templates or xsl:for-each;

4. think there are 'address' elements in your source tree, when there are
in fact none;

5. think xml:space="preserve" in your stylesheet is beneficial;

6. made a typo when you put 2 ending quotes on one of your namespace 

I'm not going to bother explaining all the things you should get from a good
book on XSLT, but I will show you a stylesheet that demonstrates the
principles you should be aware of. Against the source document you posted, use
a stylesheet that looks like this:

<?xml version="1.0" encoding="iso-8859-1"?>
  <xsl:stylesheet version="1.0"

  <!-- when processing the root node, go process the element
       children of 'chapter' element children of the 'document' 
       element child of the root node. this template is optional, 
       but saves a few cycles. -->
  <xsl:template match="/">
    <xsl:apply-templates select="document/chapter/*"/>

  <!-- when processing a 'sub' element, make a 'subOut' element -->
  <xsl:template match="sub">
      <!-- go process the children of the current 'sub' -->

  <!-- when processing a 'sup' element, make a 'supOut' element -->
  <xsl:template match="sup">
      <!-- go process the children of the current 'sup' -->

  <!-- I have no idea what you're trying to do with 'line1','line2',etc.
       so I will just guess that you want to flatten the structure and
       see only the non-whitespace-only text content. For this we don't
       even need to bother matching the 'line1' element.. just let the
       built-in templates kick in and take us to the text nodes. -->
  <!-- when processing a text node that is a child of an element whose
       name starts with 'line', copy it to the result tree 
       as long as it has some non-whitespace text -->
   <xsl:template match="*[starts-with(local-name(),'line')]/text()">
     <xsl:if test="normalize-space()">


To help understand why it works the way it does, read the XPath spec where it
talks about the data model, and the XSLT spec where it talks about built-in

   - Mike
  mike j. brown                   |  xml/xslt:
  denver/boulder, colorado, usa   |  resume:

 XSL-List info and archive:

Current Thread