xslt tutorial

Hi,

I was reading below tutorial

http://www.tizag.com/xmlTutorial/xslttemplate.php
Found a learner! Found a learner! Found a learner! Mr. Bean

i wonder why Mr. Bean  printed at e n d. please advise
LVL 7
gudii9Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Evan CutlerVolunteer Chief Information OfficerCommented:
Mr. Bean is not a student.

the xsl requests that all students be declared as "Found a learner!".

Mr. Bean is a teacher.

      <xsl:template match="student">
            Found a learner!
      </xsl:template>

The statement above is equal in java to:
if (tag == 'Student') {
     System.out.println("Grade = " + grade);
}

Hope this helps.
0
gurpsbassiCommented:
This is because XSLT uses a default template that matches everything.
XSLT provides default behavior for each node type (element, text, attribute etc).

If you want to only print out the the message when it encountered a student record, I would do something like this:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
	<xsl:for-each select="//class/student">
	  
	  <xsl:text>Found a learner!</xsl:text>
	  <xsl:text>&#10;</xsl:text>
	</xsl:for-each>
	</xsl:template>
	

</xsl:stylesheet>

Open in new window

0
Geert BormansInformation ArchitectCommented:
If I can step in here...

The question is... "why is there Mr. Bean in the end?"

Evan does not answer that question and there is some vagueness in the response. An XSLT does not "request" "decarations" and the java code is NOT close to the XSLT equivalent

 As gurpsbassi suggests, the reason is in the default templates. However default templates don't "catch all", they serve as a low priority backup. And I would not use at all the code he proposes as a solution to fix the issue... please try to use apply templates over for each, as is commonly understood to be a best practice in XSLT development

I will post two follow ups.
- one with the code for the default templates added, so the cause of the issue is apparent, the other code to fix the issue
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Geert BormansInformation ArchitectCommented:
Here is how the XSLT from the tutorial expands making the built in templates explicit

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    
    <xsl:template match="student">
        Found a learner!
    </xsl:template>
    
    <xsl:template match="*">
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match="text()">
        <xsl:value-of select="."/>
    </xsl:template>
    
    
</xsl:stylesheet>

Open in new window


The template matching "*"
will be active for both <class> and <teacher>
the <xsl:apply-templates/> in there will push out the child nodes to the templates
for <class> that means that the <student> nodes will be pushed to the template matching "student"
and the teacher node will be pushed to the template matching "*"
(the template with the most precise match will pick up the node)
for the <teacher> node the text will be pushed to the template matching "text()"... so the text content will imply be output

This explains the behaviour in detail
0
Geert BormansInformation ArchitectCommented:
and here also lays the solution...

simply add a template with a more precise match for teacher and do nothing inside

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    
    <xsl:template match="student">
        Found a learner!
    </xsl:template>
    
    <xsl:template match="teacher">
    </xsl:template>
    
    
</xsl:stylesheet>

Open in new window

0
Geert BormansInformation ArchitectCommented:
I bet you will find a similar answer in the follow up of the tutorial
0
Geert BormansInformation ArchitectCommented:
Interestingly the tutorial chooses the alternative approach...
instead of having a template that tells the stylesheet to do nothing with the teacher,
it has a template for class that selects the nodes to push out instead of all

<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>

I hope you understand this mechanism of apply templates.
Take your time to swallow it and really understand. It is the number one item to learn doing XSLT,
because it allows you to develope clear XSLTs that are very easy to maintain at a later stage

I consider the approach of the tutorial equally valuable as my suggestion.... as long as you don't use for-each for it (try to imagine processing nested structures with for-each statements nested inside for-each statements and imagin yourself confronted with a minor change to the XML source :-)
0
gurpsbassiCommented:
I agree with @Geert Bormans approach. Using apply-templates is much more modular than using for loops with nesting.

Although I'm not a fan of using empty catch-alls like :

<xsl:template match="teacher">
</xsl:template>
0
Geert BormansInformation ArchitectCommented:
Hi gurpsbassi,

It is an interesting thought and debatable, you are right.

The reason I like the no operation templates (they are not catch all templates!)
is that you can make your code very generic.
If you avoid selectors inside the apply-template, your code is slightly safer when the model changes

example: all of the following together in one stylesheet

<!-- in generic processing don't copy the teacher node -->
<xsl:template match="teacher"/>

<!-- in generic processing don't copy the teacher node inside a class -->
<xsl:template match="class/teacher"/>

<!-- however do copy the teacher node inside a team -->
<xsl:template match="team/teacher">
   <xsl:text>I am a teacher in a team</xsl:text>
</xsl:template>

You take full advantage of the prioritisation mechanism
Combine that with modes and you have very powerfull stylesheet that has splendid robustness

If you don't have select attributes in the apply-template itself, but decide what to do at the node level,
there is a better modularisation of the templates
If then you start adding them in different stylesheet files and use xsl:import versus xsl:include adequately, you can overrule and reuse chunks easily.... but that is a bit advanced for a beginners tutorial

Important for gudii9 is that (s)he learns to use apply templates instead of for-each (we both agree) The rest is a development style preference and we are both right :-)
0
gudii9Author Commented:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="class.xsl"?>
<class>
	<student>Jack</student>
	<student>Harry</student>
	<student>Rebecca</student>
	<teacher>Mr. Bean</teacher>
</class>

Open in new window

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    
    <xsl:template match="student">
        Found a learner!
    </xsl:template>
    
    <xsl:template match="teacher">
    </xsl:template>
    
    
</xsl:stylesheet>

Open in new window


is it is bug in XSL due to which it printed Mr Bean in above example?

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   
   
    <xsl:template match="student">
        Found a learner!
    </xsl:template>
   
    <xsl:template match="teacher">
    </xsl:template>
   
   
</xsl:stylesheet>

i got empty tag approach when template match is teacher.

I am still not clear on below apply template approach.
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
</xsl:stylesheet>

Open in new window

what are we trying to apply when we find match with student??
are we not supposed to find match is teacher then apply nothing in that case??
please advise
0
gudii9Author Commented:
<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>

Open in new window

//select attribute: lets you choose specific child elements.(how deep we can go. can we go to great grand child level of xml??)
//xsl:apply-templates: lets you decide when and where your xsl:template elements are used(can i specifically write like below for teacher as well??


<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="class">
    <xsl:apply-templates select="teacher"/>
</xsl:template>

<xsl:template match="student">
    Found a learner!
</xsl:template>
<xsl:template match="teacher">   
</xsl:template>

Open in new window

0
gudii9Author Commented:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="class">
    <xsl:apply-templates select="teacher"/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
<xsl:template match="teacher">
  xyz
</xsl:template>


</xsl:stylesheet>

Open in new window



which gave wrong output as below

<?xml version="1.0" encoding="UTF-8"?>
  xyz

Open in new window

please advise

i expected

<?xml version="1.0" encoding="UTF-8"?>

 Found a learner! Found a learner! Found a learner!  xyz
0
Geert BormansInformation ArchitectCommented:
In the last one

<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="class">
    <xsl:apply-templates select="teacher"/>
</xsl:template>

Open in new window


you have two completely equivalent templates with the same priority for "class"
so the processor can not know which one to choose when it needs to process the class element
Some processor will return an error,
other processors will issue a warning and pick the last one
Since you have no means to pick up the warning in a browser, you will not spot the warning but get the behaviour where only the last template for class is active.
So that explains what you saw in the last post
0
Geert BormansInformation ArchitectCommented:
To answer your question before that.

You should only have one template with the same priority for a given node to avoid confusion.

xsl:apply templates by default passes out all the child nodes. (not having a select attribute is default behaviour)
The XSLT processor will then select the template that matches the node description the best, to process this node

By using a select attribute you can be specific about which nodes (at any depth) you want to push out

Basically a good XSLT programming style will lead to many small templates in favour of a few big ones.
That can be accomplished by using apply-templates in favour of for-each
and by using predicates in the match attribute of a template in favour of xsl:choose or xs:if
0
Geert BormansInformation ArchitectCommented:
for this code
your comment

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates select="student"/>
    <xsl:apply-templates select="teacher"/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
<xsl:template match="teacher">
  xyz
</xsl:template>
</xsl:stylesheet>

Open in new window

will give the expected behaviour

but that would be equivalent to

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
<xsl:template match="teacher">
  xyz
</xsl:template>
</xsl:stylesheet>

Open in new window

my preference almost always
(note that you might want to ignore the whitespaces wone way or another)
0
gudii9Author Commented:
code snippet 1:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates select="student"/>
</xsl:template>
<xsl:template match="class">
    <xsl:apply-templates select="teacher"/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
<xsl:template match="teacher">
  xyz
</xsl:template>
</xsl:stylesheet>

Open in new window




code simippet 2:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
<xsl:template match="teacher">
  xyz
</xsl:template>
</xsl:stylesheet>

Open in new window





code snippet3:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="student">
		Found a learner!
	</xsl:template>
</xsl:stylesheet>

Open in new window


what is difference between above three code snippets.

To my eyes they almost look same.

please advise
0
gudii9Author Commented:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:template match="teacher">
		Found a learner!
	</xsl:template>
</xsl:stylesheet>

Open in new window


above gave below result

<?xml version="1.0" encoding="UTF-8"?>
      Jack
      Harry
      Rebecca
      
            Found a learner!
0
gudii9Author Commented:
<xsl:template match="blah">

above is default statement to check condition and also to display something right

<xsl:template match="class">
    <xsl:apply-templates/>//what this line means???it checks all templates?
</xsl:template>
0
gudii9Author Commented:
we need a new xsl:template that matches our XML document's root element, class. We can then pick the child student using the select attribute. Here's the XSLT code to get the job done

select attribute: lets you choose specific child elements
xsl:apply-templates: lets you decide when and where your xsl:template elements are used

both select and xsl:apply-templates both doing almost same job. What is the difference and why we need to use both together
0
Geert BormansInformation ArchitectCommented:
You are dumping a whole bunch of code and questions, but do you actually bother to read our responses?

Can you please ask one question at the time and wait for an answer, because this mess is becoming uselessy chaotic and I did a whole lot of effort to explain stuff to you, and I have a feeling you did not read it all.

So one question. We respond. You read what we write and ask for clarification if there is something you don't get. After that the next 1 question. No more word dumps that drive me mad
0
Geert BormansInformation ArchitectCommented:
I am not sure you understand the basic mechanism of apply templates

this line is a very sad one
<xsl:apply-templates/>//what this line means???it checks all templates?

because twice already in this question, I took the time to explain that to you.
So please read the whole thread back, you will find your answer

You have to understand that one particular template does something to a particular node
A node can be an element or a text node (there are others that I ignore now for simplicity)
So inside a template, a element (or a text node) is processed
But an element can have child nodes (other elements or text)
If you don't explicitely say to process them, they will not be processed
xsl:apply-templates is a mechanism to process child nodes
The way it works is as follows: apply-templates pushes the child nodes to the xslt processor
and the XSLT processor goes out to look for the best matching template
(is the most specific description of the match attribute)
"class/student" is more specific than "student"
"student" is more specific than "*"
"*" is more specific than "node()"
(I can fill this forum with the exact priority rules, and only a few XSLT developers really know them all exactly :-)
Once the best matching template for a certain node is found, the XSLT processor passes the node to this template and processing of the node begins.
Order of templates is not important (unless you have an error). It is the data that drives the processing

Now it is your task to try to understand what I just wrote. Because if you don't get this paragraph, you can continue dumping code snippets for ages, we will not make progress

You should try to apply this theory to the three code snippets you had earlier.
You did not see a real difference between the three... I can tell you they are very very different

So look at your source document. Try to play XSLT processor. Start at the root of the document. Try to find the best matching template for <class> See what it does.
And don't forget the two built in templates I showed you in my first comment.

Don't hesitate to ask for clarification. But only on this particular comment of mine. No more extensions of the question please
0
Geert BormansInformation ArchitectCommented:
both select and xsl:apply-templates both doing almost same job. What is the difference and why we need to use both together

Not exactly. xsl:apply-templates without a select attribute pushes all the child nodes to the xslt processor
Using the select attribute with a relative XPath (starting from the current node) will only push out the selected nodes (not necessary children but any nodes the 11 axes allow you to go)

I think your quote confuses the attribute select in apply templates and the attribute match in the template. It might be confusing at first becaus in your example they both can have a value "student"
BUT the one is for selecting the nodes that are pushed out to the XSLT processor, theother is for matching the nodes characteristics
0
gudii9Author Commented:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="class">
    <xsl:apply-templates/>
</xsl:template>
<xsl:template match="student">
    Found a learner!
</xsl:template>
</xsl:stylesheet>

Open in new window

i agree. Above <xsl:apply-templates  without select forced all child nodes to xslt resulting
<?xml version="1.0" encoding="UTF-8"?>
      
    Found a learner!

      
    Found a learner!

      
    Found a learner!

      Mr. Bean
0
gudii9Author Commented:
I think your quote confuses the attribute select in apply templates and the attribute match in the template. It might be confusing at first becaus in your example they both can have a value "student"
BUT the one is for selecting the nodes that are pushed out to the XSLT processor, theother is for matching the nodes characteristics

Open in new window


i got the first one which used for selecting the nodes that are pushed out to the XSLT processor.But i was not clear on second part
theother is for matching the nodes characteristics
what it means by nodes characteristics i believe you are referring

<xsl:template match="student">
    Found a learner!
</xsl:template>

please advise
0
Geert BormansInformation ArchitectCommented:
<xsl:template match="student">

yes indeed "student" is an XPath expression meaning "the element with name = student"
(the node characteristics are type is element and name is 'student')
so this match attribute will match any element "student"
0
gurpsbassiCommented:
@gudii9 please post one question/response at a time. You seem to do this in all your threads.
This is become increasingly unmanageable.
0
gudii9Author Commented:
i will post one at a time. sure.

 I think my xpath knowledge not upto mark i just finished reading that tutorial from same link and i am creating one new question on that topic
0
gurpsbassiCommented:
xslt is not something you will learn in a few hours. It requires different thinking to that of java applications.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.