![]() |
![]() | ![]() | ![]() | Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries [Thread Prev] >Thread Next - Re: xpath ancestors xpath ancestorsTo: NULL Date: 1/9/2008 4:28:00 PM Although I've been working with XSLT and XPATH expressions for some years, I am occasionally stumped about why recursing back through node parents gives me funny results. Using a named template works, using a matching template results in a stack overflow because the the parent::node() axis of the root node is again the root node. Today, in what seems to be a related unexpected result, I was using the ancestor-or-self axis and it returned an unexpected number of nodes (too many). It seems that root node is in the node list twice. I've tested this in Internet Explorer, Firefox (different XML implementations) and in oXygen using Saxon6.5.5 and all return the same results. Clearly my understanding is lacking. Could someone please explain to me why I should expect these results? Thanks Chuck Jungmann **--- banking.xml ---** <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="banking.xsl"?> <banking> <bank name="WF"> <account name="checking"/> <account name="saving"/> <account name="mortgage"/> </bank> <bank name="BankOne"> <account name="brokerage"/> <account name="creditcard"/> </bank> </banking> **-- banking.xsl --** <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:html="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="html"> <xsl:output method="xml" /> <xsl:variable name="demoNode" select="/banking/bank[@name='WF']/account[@name='saving']" /> <xsl:variable name="anc" select="$demoNode/ancestor-or-self::node()" /> <xsl:template match="/"> <html> <head><title>xpath demo</title></head> <body> <p> Expecting 3 nodes in ancestor-or-self, getting <xsl:value-of select="count($anc)" /> (four) instead. </p> <p> If I use a template to display the node list, I'll see "banking/banking/bank/account" <xsl:apply-templates select="$anc" mode="nameNode" /> </p> <p> Using a calling a named template seems to work <xsl:call-template name="makePath"> <xsl:with-param name="node" select="$demoNode" /> </xsl:call-template> </p> <p> Calling with apply-templates results in a stack-overflow: It seems that the root node is its own parent?! <!-- <xsl:apply-templates select="$demoNode" mode="makePath" /> --> </p> </body> </html> </xsl:template> <xsl:template match="node()" mode="nameNode"> <xsl:text>--</xsl:text> <xsl:value-of select="name()" /> <xsl:text>-- </xsl:text> </xsl:template> <xsl:template name="makePath"> <xsl:param name="node" /> <xsl:variable name="pnode" select="$node/parent::node()" /> <xsl:if test="$pnode"> <xsl:call-template name="makePath"> <xsl:with-param name="node" select="$pnode" /> </xsl:call-template> </xsl:if> <xsl:text>/</xsl:text> <xsl:value-of select="name($node)" /> <xsl:if test="$node/@name"> <xsl:text>[@name='</xsl:text> <xsl:value-of select="$node/@name" /> <xsl:text>']</xsl:text> </xsl:if> <xsl:template> <xsl:template match="node()" mode="makePath"> <xsl:variable name="pnode" select="parent::node()" /> <xsl:if test="$pnode"> <xsl:apply-templates select="$pnode" mode="makePath" /> </xsl:if> <xsl:text>/</xsl:text> <xsl:value-of select="name()" /> <xsl:if test="@name"> <xsl:text>[@name='</xsl:text> <xsl:value-of select="@name" /> <xsl:text>']</xsl:text> </xsl:if> </xsl:template> </xsl:stylesheet> | ![]() | ![]() | ![]() |
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | |||||
|
