p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition ISBN: 978-0-470-19274-0 (http://p2p.wrox.com/forumdisplay.php?f=398)
-   -   XSLT descendant axis problem (http://p2p.wrox.com/showthread.php?t=77038)

sarcanon November 14th, 2009 03:52 PM

XSLT descendant axis problem
I have been beating my head against the wall with an XSLT issue for a couple of hours, and I clearly am lost.

I am trying to transform some XML to HTML. The relevant portion of my source XML looks like this:


  <div xml:id="sect107" type="section" n="107">
    <head>F. Indefinite Pronouns.</head>
    <div xml:id="sect107.1" type="subsection" n="1">

And I have an XSL version 2.0 stylesheet that contains this template:


  <!-- match first <p> within <div> -->
  <xsl:template match="tei:div/tei:p[not(preceding-sibling::tei:p)]">
    <xsl:for-each select=".">
      <xsl:variable name="sectTop" select="ancestor::tei:div[@type='section'][1]/descendant::tei:p[1]=current()"/>

When this template matches the second <p> tag in my XML, I am expecting the variable $sectTop to be false, but it is in fact True. This is contrary to my (limited) understanding of how XPath expressions work. Since the <p> tag in question is the second descendant of its div ancestor, and not the first, the boolean expression should evaluate as False.

Can someone kindly enlighten me as to why I am getting this unexpected result?

I am sure this problem is a result of my ignorance, but for what it is worth, I am using Saxon-PE as my transformer.

Many thanks in advance.

samjudson November 14th, 2009 07:41 PM

My first issue with your question is that you don't say what you want your XML output to look like, so it is hard to say if we are misunderstanding your intentions.

Firstly, I would make two templates, one matching the div, and then only processing the first p within in - this is far less intensive that using the preceding-sibling axis:

<xsl:template match="tei:div">
<xsl:apply-template select="tei:p[1]"/>

<xsl:template match="tei:div/tei:p">

I'm not sure the purpose of the <xsl:for-each> is as it does nothing.

Something like the following may work for the last part:

<xsl:variable name="sectTop" select=../../tei:div[@type='section'][1]/tei:p[1]=."/>

mhkay November 14th, 2009 08:35 PM

All the p elements in your example are empty, therefore they are all equal. I suspect you want the "is" operator rather than "=".

sarcanon November 14th, 2009 10:19 PM


Originally Posted by mhkay (Post 249519)
All the p elements in your example are empty, therefore they are all equal. I suspect you want the "is" operator rather than "=".

Fantastic! I know I was doing something wrong, and confusing node equality with general equality was precisely the problem.

But I don't feel too badly now seeing that comparisons take up in excess of 8 pages (!) in the XPath chapter of your fine book.

Thank you so much.

sarcanon November 14th, 2009 10:20 PM

Thank you very much, but I think that Michael Kay hit the nail on the head.

All times are GMT -4. The time now is 11:36 AM.

Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.