 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

October 1st, 2008, 05:35 AM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
|
|
preceding-sibling::comment()
Hi, I am trying to get the value of a preceding comment. In the below example, If my context node is "foo", how do I get the comment immediately before the "foo" element.
Code:
<root>
<data>Some Data</data>
<foo>Some Foo</foo>
</root>
The below xslt returns all the preceding comments. I just want "This is the comment I want" .
Code:
<xsl:for-each select="foo">
<xsl:value-of select="preceding-sibling::comment()"/>
</xsl:for-each/>
Thanks for the help.
Bones
|
|

October 1st, 2008, 05:49 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
preceding-sibling::comment()[1]
will return the most recent preceding sibling comment
preceding-sibling::node()[1][self::comment()]
will return the immediately preceding node if and only if it is a comment
preceding-sibling::node()[not(self::text()[.=''])][1][self::comment()]
will return the immediately preceding node, ignoring whitespace-only text nodes, if and only if it is a comment
Take your pick.
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer's Reference
|
|

October 1st, 2008, 06:33 AM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
|
|
Hi Michael,
Thank you for the help. Using
Code:
preceding-sibling::node()[1][self::comment()]
Returns nothing. I am probably missing something.
Here is my actual input:
Code:
<xsl:template match="ACM:PARA">
<fo:inline font-family="{$default-font}" font-size="{$default-font-size}">
<xsl:apply-templates/>
</fo:inline>
</xsl:template>
Here is my xsl:
Code:
<xsl:for-each select="//xsl:template[@match]">
<template type="match" base="{subsequence(reverse(tokenize(document-uri(/), '/')), 1, 1)}">
<xsl:copy-of select="@*"/>
<xsl:attribute name="line"><xsl:value-of select="saxon:line-number()"/></xsl:attribute>
<xsl:attribute name="comments"><xsl:value-of select="preceding-sibling::node()[1][self::comment()]"/></xsl:attribute>
<xsl:value-of select="@match"/>
</template>
</xsl:for-each>
Some background - I am writing a stylesheet to describe stylesheets - Something similar to java Docs.
Thanks for the help.
|
|

October 1st, 2008, 06:46 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
There is a text node with white space between the comment and the xsl:template element. Therefore preceding-sibling::node()[1][self:comment()] is empty. I think you want preceding-sibling::comment()[1] instead.
--
Martin Honnen
Microsoft MVP - XML
|
|

October 1st, 2008, 07:00 AM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
|
|
Thanks Martin,
preceding-sibling::comment()[1] selects the last preceding comment() even if its not the immediately preceding node.
Any other thoughts?
|
|

October 1st, 2008, 07:08 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
It is not clear which comment nodes exactly you are looking for.
As I said, in your sample input the comment is not the immediately preceding node as there is a text node with white space between the comment and the xsl:template element.
Nevertheless I thought you want to select that comment.
Perhaps
preceding-sibling::node()[not(self::text()[normalize-space(.)=''])][1][self::comment()]
is more what you want.
--
Martin Honnen
Microsoft MVP - XML
|
|

October 1st, 2008, 07:13 AM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
|
|
Thanks Martin,
Code:
preceding-sibling::node()[not(self::text()[normalize-space(.)=''])][1][self::comment()]
Works :)
What is unclear to me is the mention of whitespace. Where is the whitespace?
|
|

October 1st, 2008, 07:19 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
If you have
then the foo element node is preceded and succeeded directly by a comment node.
However with
there is a text node with white space between each comment node and the element node.
--
Martin Honnen
Microsoft MVP - XML
|
|

October 1st, 2008, 07:27 AM
|
|
Friend of Wrox
|
|
Join Date: Jul 2006
Posts: 430
Thanks: 28
Thanked 5 Times in 5 Posts
|
|
Thank you for the clarification.
Given the following example:
I assumed the line break was not considered whitespace.
Thanks again,
Bones
|
|

October 1st, 2008, 08:03 AM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
Nope, the line breaks are exactly what IS considered whitespace (along with spaces and tabs).
/- Sam Judson : Wrox Technical Editor -/
|
|
 |