Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

axis

 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
<chapter>
<sect xml:lang="de">
<warning>Make a backup first.</warning>
</sect>
</chapter>
ancestor::warning does it include sect and chapter
ancestor-self::warning does it include sect and chapter and warning
I am not able to write a example that would print me ancestor .. this is what i wrote
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="warning">
<xsl:value-of select="ancestor::warning"/>
</xsl:template>
</xsl:stylesheet>
does'nt print any thing
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shan,
When you say "template match='warning'", you are already in the context of the warning node. Hence you should not mention ancestor::warning to print the ancestor of warning. When you say so, it is looking for "warning" nodes in the ancestor list of "warning" and since there are none, its printing nothing. In fact, in the example xml given by you warning node has 2 ancestors (immediate parent, its parent, so on upto the root node). Please go through the xpath pdf document by OReilly mentioned earlier for complete description of different kinds of axes.
You can also mention something like -
<xsl:for-each select="preceding::* | ancestor::*">
to select both the preceding nodes as well as the ancestors in the list.
Please come back if you have any further questions.
 
Dan Drillich
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shan,
Nothing is being printed because the ancestors of warning contain no text.
Please try the following -

Cheers,
Dan
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Dan,
I believe that the way in which Shan is trying to address the ancestor "ancestor::warning" is wrong. This tries to select the warning nodes in the list of ancestors and not "the ancestors of warning" as per our intention.
Coming to the point where you see the text appearing is not bcoz of the template for warning getting executed, but due to the default processing rules for templates for text() nodes.
That disappears when you suppress the default processing for the text nodes as following to do nothing ----------
<xsl:template match="text()"/>
Please try this stylesheet and you can see that both 1 and 3 get printed, whereas the sample element containing 3 is not an ancestor, but a sibiling of warning.
=================================================
<chapter>1
<sect xml:lang="de">
<sample> 3 </sample>
<warning>Make a backup first.</warning>
</sect>
</chapter>
=================================================
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="warning">
<xsl:value-of select="ancestor::warning"/>
</xsl:template>
</xsl:stylesheet>
================================================
Please come back with your comments/suggestions on this.
 
Dan Drillich
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jayadev,
You are right!
The template that will yield the results Shan expected with ancestor would be -

Cheers,
Dan
 
Anonymous
Ranch Hand
Posts: 18944
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I want to know How I can I write program that ouputs sect and chapter when I ask for ancestor of warning? How should i go about in doing this?
 
Jayadev Pulaparty
Ranch Hand
Posts: 662
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Shan,
Please try this out and interpret the result ....
===============================================
<chapter>chapter
<sect xml:lang="de">sect
<warning>Make a backup first.</warning>
</sect>
</chapter>
================================================
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- These are comments -->
<xsl:template match="warning">
<!-- Loop on the ancestors of warning -->
<!-- print name of ancestor, its text content -->
<xsl:for-each select="ancestor::*">
<xsl:value-of select="name()"/>
<xsl:text>::</xsl:text>
<xsl:value-of select="text()"/>
</xsl:for-each>
</xsl:template>
<!-- Supress default template for text nodes -->
<xsl:template match="text()"/>
</xsl:stylesheet>
=================================================
Please come back if you need any further information.
 
Dan Drillich
Ranch Hand
Posts: 1183
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jayadev,
Lovely code!
According to http://www.ibiblio.org/xml/books/bible2/chapters/ch17.html#d1e2003 xsl:for-each and xsl:apply templates are equivalent.
I tried to convert Jayadev's solution to use the xsl:apply-templates command instead of the xsl:for-each one.
My best so far looks like -

Can anybody improve it to be a generic solution, meaning - without hard-coding rules for the ancestors?
Cheers,
Dan
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic