.CDATA showing up at end of output files

D

Dimitre Novatchev

You seem to be unaware of the xslt processing which uses the built-in
rules in the absence of templates that match some selected node.

http://www.w3.org/TR/xslt#built-in-rule

According to the XSLT processing model:

http://www.w3.org/TR/xslt#section-Processing-Model

the root node will be processed by a built-in rule, because you do not
specify a template matching '/'.

The equivalent of this built-in rule will be applied:

<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>

It applies templates to all children (the root node always has a
single child element-- the top element) -- that is to the rdf:RDF
element and to a whitespace-only node.

No template is specified for this element, therefore the same built-in
rule will be applied again on this element and the result will be to
apply templates to all of its children.

And so on ... You have not specified a matching template for any of
the nodes in the source xml document.

Eventually in this process of applying a built-in rule, a built-in
rule will be applied on the problematic-string element. It will apply
templates on its children. The problematic-string element has a single
child -- text node (a CDATA is just a text node).

The built-in rule for a text node is:

<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>

It simply copies the text to the output.


This is how you get the result of applying your transformation.



A common rule of thumb is that if the result contains some unaccounted
for text from the source.xml, then most probably the transformation
didn't include a matching template for some nodes (nor did it exclude
such nodes from processing) and this led to the instantiation of the
built-in template rules which copy all descendent text nodes of the
elements they match.


=====
Cheers,

Dimitre Novatchev.
http://fxsl.sourceforge.net/ -- the home of FXSL






Hello,

This seems like a newbie question, but I couldn't find the answer on
google.
I've been using xsl to transform rdf files into runnable
programs in another (non-markup) language. It's been great except for a
minor hiccup - all text within CDATA blocks shows up at the end of my
output files without being invited.
I think I've boiled it down to a specific problem, but I'd like to better
understand why it is a problem at all.

I'm using xalan 2.5.1 on Linux with java 1.4.0.

Here is a sample rdf file for the demonstration:

<?xml version='1.0' encoding='ISO-8859-1'?> <!DOCTYPE rdf:RDF [
<!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'> <!ENTITY
rdfs 'http://www.w3.org/TR/1999/PR-rdf-schema-19990303#'>
]>
<rdf:RDF xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;">
<test>
<problematic-string xml:space='preserve'><![CDATA[My cdata block]]>
</problematic-string>
</test>
</rdf:RDF>


Now here are two simple scripts - one that works as I would expect and one
that doesn't.

Good script:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/TR/1999/PR-rdf-schema-19990303#"
version="1.0">

<xsl:eek:utput method="text" indent="no"/> <xsl:strip-space elements="*"/>

<xsl:template match="test">
<xsl:text>Here is where I want the text: </xsl:text>
<xsl:call-template name="test"/>
</xsl:template>

<xsl:template name="test">
<xsl:for-each select="problematic-string">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

This one produces an output file that contains the line: 'Here is where I
want the text: My cdata block'

Now for the bad script (with only one small difference):

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/TR/1999/PR-rdf-schema-19990303#"
version="1.0">

<xsl:eek:utput method="text" indent="no"/> <xsl:strip-space elements="*"/>

<xsl:template match="bad-test"> <!-- ***The only difference -->
<xsl:text>Here is where I want the text: </xsl:text>
<xsl:call-template name="test"/>
</xsl:template>

<xsl:template name="test">
<xsl:for-each select="problematic-string">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>


This one produces the following output: 'My cdata block'


Now my question is: why does the second script produce any output at all?
Do I have to explicitly match every node with CDATA even if I have no use
for them?

Thanks for your time,
Isaac
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top