Any XSL experts?

M

Mark Space

Here's a problem that's driving me nuts.

The program below executes correctly as is. There's one line in the xsl
string commented out. If you uncomment that line, the output changes.
It adds the line "I can't jump." That's the value of the <jump> tag.
But I don't ask for this tag to be put in the output anywhere in the xsl
file, so I don't understand why it's appearing in the output.

Can anyone shed some illumination on this conundrum?


package xslweirdness;

import java.io.StringReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Main {

private final static String xml = "<?xml version=\"1.0\"?>\n"
+" <monkey>\n"
+" <boy can=\"no\">\n"
+" <jump>I can't jump.</jump>\n"
+" </boy>\n"
+" </monkey>";
private final static String xsl = "<xsl:stylesheet "
+"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" "
+"version=\"1.0\">\n"
+" <xsl:eek:utput method=\"html\"/>"
+" <xsl:template match=\"/monkey\" >\n"
+" Jumping: <xsl:value-of select=\"boy/@can\" />\n"
// +" <xsl:apply-templates/>"
+" </xsl:template>\n"
+"</xsl:stylesheet>";

public static void main(String[] args) throws Exception {
System.out.println( "XML:--------------------\n" + xml );
System.out.println( "XSL:--------------------\n" + xsl );

StreamSource xslSrc = new StreamSource( new StringReader(xsl) );
TransformerFactory tf = TransformerFactory.newInstance();
Transformer xfrm = tf.newTransformer(xslSrc);
StreamResult stmOut = new StreamResult( System.out );
StreamSource xmlSrc = new StreamSource( new StringReader(xml) );

System.out.println( "transform:--------------------\n" );
xfrm.transform(xmlSrc, stmOut);
}
}
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Mark said:
Here's a problem that's driving me nuts.

The program below executes correctly as is. There's one line in the xsl
string commented out. If you uncomment that line, the output changes.
It adds the line "I can't jump." That's the value of the <jump> tag.
But I don't ask for this tag to be put in the output anywhere in the xsl
file, so I don't understand why it's appearing in the output.

Can anyone shed some illumination on this conundrum?
private final static String xml = "<?xml version=\"1.0\"?>\n"
+" <monkey>\n"
+" <boy can=\"no\">\n"
+" <jump>I can't jump.</jump>\n"
+" </boy>\n"
+" </monkey>";
private final static String xsl = "<xsl:stylesheet "
+"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" "
+"version=\"1.0\">\n"
+" <xsl:eek:utput method=\"html\"/>"
+" <xsl:template match=\"/monkey\" >\n"
+" Jumping: <xsl:value-of select=\"boy/@can\" />\n"
// +" <xsl:apply-templates/>"
+" </xsl:template>\n"
+"</xsl:stylesheet>";

That line tells the XSLT processor to process stuff inside what
you have found.

There are the element text inside.

And apperently there are a default template that displays.

I guess you don't want that line !

Arne
 
A

Andrew Thompson

Mark Space wrote:

Sub: Any XSL experts?

I probably should not answer this, since I do not
consider myself an 'expert' on anything.

OTOH - I'll make a WAG.*

<http://www.w3schools.com/xsl/xsl_apply_templates.asp>
"The <xsl:apply-templates> element applies a template
to the current element *or to the current element's child
nodes.*"

My use of *bold*.

If that line is changed to ..
+" <xsl:apply-templates select='boy'/>"
..the "I can't jump." line is printed, if changed to..
+" <xsl:apply-templates select='monkey'/>"
..it is not.

* My WAG is - that line prints because you 'told it to'.

--
Andrew Thompson
http://www.athompson.info/andrew/

Message posted via JavaKB.com
http://www.javakb.com/Uwe/Forums.aspx/java-general/200710/1
 
M

Mike Schilling

Mark said:
Here's a problem that's driving me nuts.

The program below executes correctly as is. There's one line in the
xsl string commented out. If you uncomment that line, the output
changes. It adds the line "I can't jump." That's the value of the
<jump> tag. But I don't ask for this tag to be put in the output
anywhere in the xsl file, so I don't understand why it's appearing in
the output.

<apply-templates> means to process all child nodes. The default action for
a text node, which you haven't overridden, is to output the text.
 
M

Mark Space

Arne said:
There are the element text inside.

And apperently there are a default template that displays.

Yeah that's a good way of thinking about it. There's a default element
that says to just print all values. Weird, I think, but I guess that's
how it works. Thanks!
 
M

Mark Space

Andrew said:
<http://www.w3schools.com/xsl/xsl_apply_templates.asp>
"The <xsl:apply-templates> element applies a template
to the current element *or to the current element's child
nodes.*"

My use of *bold*.

If that line is changed to ..
+" <xsl:apply-templates select='boy'/>"
.the "I can't jump." line is printed, if changed to..
+" <xsl:apply-templates select='monkey'/>"
.it is not.

* My WAG is - that line prints because you 'told it to'.

As Arne said, there appears to be a default element. In a "real" xsl
file there are a lot more xsl:templates. I assumed those would be
matched. The presence of a "default" template really kinda fouls things
up, imo. I appreciate that you pointed out that the select command
could be used to modify this behavior, that's probably just what I need.
I'm still trying to wrap my head around how the parse "sees" the
transform.

Thanks for the info!
 
M

Mark Space

Mike said:
<apply-templates> means to process all child nodes. The default action for
a text node, which you haven't overridden, is to output the text.

That makes more sense: because no action was specified, a default one
was supplied. Thanks!


I'm still trying to wrap my head around how the processing actually
occurs. Since this is just basically a fun project, it doesn't matter
if I can ultimately get everything working just perfect. That's good,
because the more I look at the actual input file, the more it appears it
was not designed with any kind of XSL in mind.
 
P

Pavel Lepin

Follow-ups set to comp.text.xml.


The meaning of xsl:apply-templates without select attribute
is described in detail in XSLT 1.0 spec, 5.4. Built-in
template rules are described in 5.8.
I'm still trying to wrap my head around how the processing
actually occurs.

Unless I've mistaken the intent of your question, here's the
gist of how XSLT processing works:

An XSLT stylesheet is a set of templates describing how to
construct result tree fragments, using literal result
elements, xsl:element, xsl:attribute, xsl:value-of etc.
Those templates are applied to various node lists.

Of particular interest is xsl:apply-templates and similar
constructs (xsl:apply-imports, xsl:for-each). Those
construct a resulting tree fragment by selecting a nodeset
(by evaluating an XPath expression in select attribute if
specified, or as described in 5.4 otherwise), using it as
current node list and applying templates to it.

The template chosen for every node or attribute in a node
list depends on a set of hairy rules described in 5.5,
involving stuff like 'import precedence', template
specificity, priority attributes on corresponding
xsl:template elements, mode attribute of
xsl:apply-templates, and the particular instruction invoked
to apply templates, but most of that is of little interest
unless/until you run into problems with it.

To start the transformation, an XSLT processor selects the
document node (/) as a current node list and applies
templates to it. The process continues recursively until a
template is reached that constructs a resulting tree
fragment without applying templates to anything else.

How does that work with your sample document and stylesheet:

1. Current node list: document node (/).
Template applied (built-in):

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

2. Current node list: root element 'monkey'.
Template applied:

<xsl:template match="/monkey">
 Jumping: <xsl:value-of select="boy/@can"/>
 <xsl:apply-templates/>
</xsl:template>

3. Current node list: element 'boy'.
Template applied (built-in):

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

4. Current node list: element 'jump'.
Template applied (built-in):

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

5. Current node list: text node 'I can't jump'.
Template applied (built-in):

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

The RTF for 5 therefore is:

I can't jump.

For 4 and 3:

I can't jump.

For 2:

Jumping: no
I can't jump.

For 1:

Jumping: no
I can't jump.
That's good, because the more I look at the actual input
file, the more it appears it was not designed with any
kind of XSL in mind.

I fail to see what leads you to this conclusion.

Oh, and:

Andrew Thompson said:
<http://www.w3schools.com/xsl/xsl_apply_templates.asp>
"The <xsl:apply-templates> element applies a template
to the current element *or to the current element's child
nodes.*"

Just goes to show you how little clue those guys at
w3schools have. Not the first time they've been caught at
blatant lies, either.
 

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

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top