You are viewing a plain text version of this content. The canonical link for it is here.
Posted to docs@cocoon.apache.org by da...@cocoon.zones.apache.org on 2005/09/21 16:51:52 UTC

[DAISY] Created: XSLT FAQs

A new document has been created.

http://cocoon.zones.apache.org/daisy/legacydocs/711.html

Document ID: 711
Branch: main
Language: default
Name: XSLT FAQs
Document Type: Document
Created: 9/21/05 2:51:47 PM
Creator (owner): Helma van der Linden
State: publish

Parts
=====

Content
-------
Mime type: text/xml
Size: 7425 bytes
Content:
<html>
<body>

<h2>How do I tell Cocoon to stop adding carriage-returns during XSL
transformation?</h2>

<p>The short answer is that this is not a Cocoon issue. You need to read up on
XSLT usage. Please see
<a href="http://cocoon.apache.org/community/mail-lists.html">other resources for
XSLT,</a> specifically, the XSL FAQ and discussion lists.</p>

<p>The long answer is that you need to use the XSLT function</p>

<pre>normalize-space()</pre>

<p>whenever you want to rely on the content of an xml element.</p>

<p>For example, if your application is producing some Javascript code in your
HTML output, then you might mistakenly try to use the following construct in
your XSL stylesheet:</p>

<pre>alert('&lt;xsl:value-of select="message"/&gt;');</pre>

<p>which will produce:</p>

<pre>alert('
messageValue
');
</pre>

<p>The line-endings in the content of your "message" element will cause
javascript errors. Instead, do this:</p>

<pre>alert('&lt;xsl:value-of select="normalize-space(message)"/&gt;');
</pre>

<p>Note that there are many more issues about whitespace handling. Please refer
to the relevant XSLT resources rather than clutter up the Cocoon discussion
lists.</p>

<h2>Is (your description here) kind of functionality appropriate for a
stylesheet?</h2>

<p>When this kind of question arises, ask yourself:</p>

<ul>
<li>Am I using my stylesheet to address style concerns, or am I programming with
it?</li>
<li>Could I solve this problem once and for all during Generation?</li>
<li>Isn't my problem better solved with a Transformer, since it requires coding?
</li>
</ul>

<p>There is not one, nor only one, answer. In Cocoon, you can accomplish the
same thing in a number of different ways. Nonetheless, if your transformation
depends on something specific happening during generation, it will be more
difficult to reuse your code.</p>

<p>Here's a hint. Do all that you possibly can in a Generator. Add only what is
absolutely necessary with Transformers. Use stylesheets to change format or
style, not to code. This approach will make your system more manageable and
reusable because it removes dependencies between components.</p>

<h2>Can I use the same XSLT processor and still specify different processing
options for different pipelines?</h2>

<p>For example, I found that PDF processing is faster with Xalan when I turn
incremental processing off.</p>

<p>Yes. For Cocoon version 2.0.3, check out the following
<a href="../snippet/snippet-xslt-options.html">Cocoon snippet.</a></p>

<h2>Can I use different XSLT processors when processing different pipelines?
</h2>

<p>Yes. For Cocoon version 2.0.3, adapt the approach discussed in the following
<a href="../snippet/snippet-xslt-options.html">Cocoon snippet.</a></p>

<h2>How can I remove namespaces from my xml files?</h2>

<p>Sometimes adding xsl:exclude-result-prefixes attributes to the
&lt;xsl:stylesheet&gt; or literal result element is not effective in removing
all namespace declarations. For example, namespace nodes copied from the source
document within &lt;xsl:copy&gt; or &lt;xsl:copy-of&gt; instructions (commonly
found in catch-all stylesheet templates) will not be excluded.</p>

<p>There are two approaches to this problem.</p>

<p>One approach is to add a transformation step in your pipeline (or adjust your
final stylesheet) with the following:</p>

<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  &lt;xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/&gt;
    &lt;xsl:template match="*"&gt;
      &lt;!-- remove element prefix (if any) --&gt;
      &lt;xsl:element name="{local-name()}"&gt;
        &lt;!-- process attributes --&gt;
        &lt;xsl:for-each select="@*"&gt;
          &lt;!-- remove attribute prefix (if any) --&gt;
          &lt;xsl:attribute name="{local-name()}"&gt;
            &lt;xsl:value-of select="."/&gt;
          &lt;/xsl:attribute&gt;
        &lt;/xsl:for-each&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/xsl:element&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

</pre>

<p>Another approach is to extend your serializer component, described
<a href="faq-serializers.html#faq-4">here</a>.</p>

<h2>What's "wrong" with use of the document() function in Cocoon?</h2>

<p>Using the document() function for aggregation in Cocoon may break Separation
of Concerns (SoC). That is, the designers of Cocoon view inclusion and
transformation as different functions, best handled by separate Cocoon
components. Treating them separately allows you to achieve performance gains and
increases the resusability of your pipelines.</p>

<p>Alternatives to the document() in the Cocoon environment include aggregation
or the use of a multi-stage transformation using the XInclude Transformer. This
involves transforming a list of documents (generated dynamically or statically)
by adding xinclude elements which reference (via xpointer) specific document
content, and then transforming again via the XInclude Transformer, to obtain the
desired result. For an example of this, see this
<a href="http://marc.theaimsgroup.com/?l=xml-cocoon-users&amp;m=102617106411067&amp;w=2">email.</a>
</p>

<p>You'll achieve better performance if you aggregate content prior to
transformation. This allows you to take full advantage of Cocoon's pipeline
caching. In contrast, making dynamic document() calls inside an XSLT within a
cached pipeline is problematic. At this time, Cocoon does not recognize changes
in documents (called by the document() function) until the requested page
expires from cache.</p>

<p>Understand that the document() function was designed *before* xinclude with
xpointer facilities existed. Had such capabilities been available, perhaps the
document() function, which essentially mimics xinclude and xpointer, would have
never been added to XSLT.</p>

<p>Please note that if you must work with your XML files outside of the Cocoon
environment, you may need to use the document() function in order to utilize the
limited capabilities of other pipeline engines. This includes engines which are
not xinclude-capable or which lack a predefined way to indicate document
processing steps. If you are working with legacy code from non-pipelined
engines, you may need to use the document() function as well, at least
initially.</p>

<p>If you do use the document() function in Cocoon, you can still observe SoC by
having separate XSLT stylesheets perform inclusion and transformation functions.
For example, you can put multiple XSLT transforms in a pipeline and have the
first one perform inclusion and the second one perform transformation. However,
be mindful of some unresolved caching issues in Cocoon related to the document()
function. At this time, Cocoon is unable to check validity of content included
via the document() function. In addition, the document() function implemented by
Xalan is inefficient. See:
<a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=4257">Issue 4257</a>
and <a href="http://issues.apache.org/bugzilla/show_bug.cgi?id=28341">Issue
28341</a>. Until this bug is fixed, consider using Saxon instead for document()
function-related parsing needs.</p>

<p>For other aggregation/inclusion approaches, please stay tuned for
XpathDirectoryGenerator (2.1 scratchpad), as well as Forrest's Libre (currently
alpha in the Forrest cvs).</p>

</body>
</html>

Collections
===========
The document belongs to the following collections: legacydocs