This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: searching and replacing


normbishop1@netscape.net 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 
declarations;


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"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <!-- 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/*"/>
  </xsl:template>

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

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

  <!-- 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()">
       <xsl:copy/>
     </xsl:if>
   </xsl:template>

</xsl:stylesheet>

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
templates.

   - Mike
____________________________________________________________________________
  mike j. brown                   |  xml/xslt: http://skew.org/xml/
  denver/boulder, colorado, usa   |  resume: http://skew.org/~mike/resume/

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]