Difference between revisions of "Copy-All.xsl"

From TEIWiki
Jump to navigation Jump to search
m
 
m
 
(14 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
[[Category:P4toP5]]
 
[[Category:P4toP5]]
 
[[Category:XSLT]]
 
[[Category:XSLT]]
This is a utility XSLT script.  It should be placed in the same directory as PipedStylesheets.bash and the other XSLT stylesheets you want to use.  (They import this one.)  However, in naming this stylesheet make sure to call it 'Copy-All.xsl'.  Specifically, make sure you have it capitalised, and that it ends '.xsl' not '.xslt' as the other stylesheets.
 
  
You can use this stylesheet as well to copy the entire contents of an XML document *except* do something to some particular elementsThe fictional element '''fooBar''' is used as an example of how one would do that.
+
== Introduction ==
 +
This is a utility XSLT script which copies the entire contents of an XML document to the output, except those elements specifically matched.
 +
One manner in which to use it is to include the statement:
 +
  <nowiki><xsl:import href="Copy-All.xsl"/></nowiki>
 +
at the beginning of your XSLT(See the [[:Category:P4toP5|P4toP5]] stylesheets which do this as an example.)
  
 +
The concept of this approach is called ''identity transform'' (see [http://en.wikipedia.org/wiki/Identity_transform Wikipedia]).
 +
 +
== Use with "PipedStylesheets.bash" and "P4 enroute to P5.bash" ==
 +
If using either of these bash scripts to pipeline a number of XSLT transformations, this stylesheet should be placed in the same directory as the script and the other stylesheets.  (They import this one.)  However, in naming this stylesheet make sure to call it 'Copy-All.xsl'.  Specifically, make sure you have it capitalised, and that it ends '.xsl' not '.xslt' as the other stylesheets.
 +
 +
== General Purpose Use ==
 +
You can use this stylesheet as the basis of one to copy the entire contents of any XML document *except* do something to some particular elements.  The fictional element '''fooBar''' is used as an example of how one would do something different to a particular element.  However,  if you are going to write several stylesheets, each using this functionality, then importing it in as above probably a better idea.
 +
 +
== Stylesheet ==
 +
<pre><nowiki><?xml version="1.0"?>
 +
<xsl:stylesheet version="1.0"
 +
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 +
 +
  <!-- XSLT Template to copy anything, priority="-1" -->
 +
  <xsl:template match="@*|node()" priority="-1">
 +
    <xsl:copy>
 +
      <xsl:apply-templates select="@*|node()"/>
 +
    </xsl:copy>
 +
  </xsl:template>
 +
 +
  <!-- If I were to do something different for an element here is how I'd do it. -->
 +
  <xsl:template match="fooBar">
 +
    <barFoo><xsl:apply-templates/></barFoo>
 +
  </xsl:template>
 +
 +
</xsl:stylesheet>
 +
 +
</nowiki></pre>
 +
 +
== P5 namespace version ==
 +
If you are processing a TEI P5 document, whose elements will therefore be in the TEI namespace, and if you have an XSLT 2.0 processor, the following variant of the stylesheet makes your life easier by defining the <tt>xpath-default-namespace</tt> attribute on the stylesheet so that you can omit the <tt>tei:</tt> prefix in your XPath expressions:
 
<pre><nowiki>
 
<pre><nowiki>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+
<?xml version="1.0"?>
  version="1.0">
+
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
 +
  xpath-default-namespace="http://www.tei-c.org/ns/1.0">
  
<!-- XSLT Template to copy anything, priority="-1" -->
+
  <!-- XSLT Template to copy anything, priority="-1" -->
<xsl:template match="@*|node()|comment()|processing-instruction()" priority="-1">
+
  <xsl:template match="@*|node()" priority="-1">
<xsl:copy><xsl:apply-templates select="@*|node()|comment()|processing-instruction()"/></xsl:copy>
+
    <xsl:copy>
</xsl:template>
+
      <xsl:apply-templates select="@*|node()"/>
 +
    </xsl:copy>
 +
  </xsl:template>
  
<!-- If I was to do something different for an element here is how I'd do it. -->
+
  <!-- If I were to do something different for an element here is how I'd do it. -->
<xsl:template match="fooBar">
+
  <xsl:template match="fooBar">
<barFoo><xsl:apply-templates/></barFoo>
+
    <barFoo><xsl:apply-templates/></barFoo>
</xsl:template>
+
  </xsl:template>
  
 
</xsl:stylesheet>
 
</xsl:stylesheet>
 +
</nowiki></pre>
 +
 +
== More efficient version ==
 +
The “identity transform” used in the above versions is very easy for the humans to write, and pretty easy to understand. But it is potentially quite in efficient, because for '''every''' node the processor has to go around applying templates and building little result tree fragments, even for those nodes for which there never is anything inside it, in which case just copying the node to the result tree is (in theory) faster.
 +
 +
This version copies those nodes that can be copied, and applies templates only to those nodes that need the extra overhead. Here are just the templates for the identity transform itself (not the rest of the stylesheet).
  
</pre></nowiki></pre>
+
<pre><nowiki>  <xsl:template match="comment()|processing-instruction()|text()">
 +
    <xsl:copy/>
 +
  </xsl:template>
 +
  <xsl:template match="*">
 +
    <xsl:copy>
 +
      <xsl:copy-of select="@*"/>
 +
      <xsl:apply-templates select="comment()|processing-instruction()|text()|*"/>
 +
    </xsl:copy>
 +
  </xsl:template>
 +
</nowiki></pre>

Latest revision as of 14:17, 9 April 2011


Introduction

This is a utility XSLT script which copies the entire contents of an XML document to the output, except those elements specifically matched. One manner in which to use it is to include the statement:

 <xsl:import href="Copy-All.xsl"/>

at the beginning of your XSLT. (See the P4toP5 stylesheets which do this as an example.)

The concept of this approach is called identity transform (see Wikipedia).

Use with "PipedStylesheets.bash" and "P4 enroute to P5.bash"

If using either of these bash scripts to pipeline a number of XSLT transformations, this stylesheet should be placed in the same directory as the script and the other stylesheets. (They import this one.) However, in naming this stylesheet make sure to call it 'Copy-All.xsl'. Specifically, make sure you have it capitalised, and that it ends '.xsl' not '.xslt' as the other stylesheets.

General Purpose Use

You can use this stylesheet as the basis of one to copy the entire contents of any XML document *except* do something to some particular elements. The fictional element fooBar is used as an example of how one would do something different to a particular element. However, if you are going to write several stylesheets, each using this functionality, then importing it in as above probably a better idea.

Stylesheet

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

  <!-- XSLT Template to copy anything, priority="-1" -->
  <xsl:template match="@*|node()" priority="-1">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- If I were to do something different for an element here is how I'd do it. -->
  <xsl:template match="fooBar">
    <barFoo><xsl:apply-templates/></barFoo>
  </xsl:template>

</xsl:stylesheet>

P5 namespace version

If you are processing a TEI P5 document, whose elements will therefore be in the TEI namespace, and if you have an XSLT 2.0 processor, the following variant of the stylesheet makes your life easier by defining the xpath-default-namespace attribute on the stylesheet so that you can omit the tei: prefix in your XPath expressions:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
   xpath-default-namespace="http://www.tei-c.org/ns/1.0">

  <!-- XSLT Template to copy anything, priority="-1" -->
  <xsl:template match="@*|node()" priority="-1">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- If I were to do something different for an element here is how I'd do it. -->
  <xsl:template match="fooBar">
    <barFoo><xsl:apply-templates/></barFoo>
  </xsl:template>

</xsl:stylesheet>

More efficient version

The “identity transform” used in the above versions is very easy for the humans to write, and pretty easy to understand. But it is potentially quite in efficient, because for every node the processor has to go around applying templates and building little result tree fragments, even for those nodes for which there never is anything inside it, in which case just copying the node to the result tree is (in theory) faster.

This version copies those nodes that can be copied, and applies templates only to those nodes that need the extra overhead. Here are just the templates for the identity transform itself (not the rest of the stylesheet).

  <xsl:template match="comment()|processing-instruction()|text()">
    <xsl:copy/>
  </xsl:template>
  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="comment()|processing-instruction()|text()|*"/>
    </xsl:copy>
  </xsl:template>