Subject: Re: [xsl] test for ancestral attribute returning variant results From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sun, 24 Oct 2021 19:02:58 -0000 |
Haven't gone deep into this (and after a single reading I am not sure I understand what is the alleged problem at all), but at a glance it seems quite possible that the use of the "!=" operator may be the culprit of some unexpected behavior. My advice is to always use the not() function instead of the "!=" operator, unless one is absolutely certain "!=" is really needed. Thanks, Dimitre On Sun, Oct 24, 2021 at 10:42 AM Trevor Nicholls trevor@xxxxxxxxxxxxxxxxxx < xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > Hi > > > > (What follows is XSL 2.0 and the processor I am using is Saxon, I have > tried with Saxon versions 8.7.3, 9.9 and 10.0 and all exhibit the same > behaviour.) > > > > I am at a complete loss to explain why this is happening. > > > > My XML documents conform to a schema which allows many elements to have a > 'version' attribute. An element's version serves as a default for all > descendants, although it can be overridden on any descendant subtree by > another version on the descendant node. In many cases an element will have > an unnecessary version specified (because it is the same as the nearest > ancestral version). > > > > I have a named template (versiontest) which is called on elements to > construct a version callout in the margin. The version should appear if it > is different to that of the parent, or if the ancestral element with the > same version appears on an earlier page. > > > > My problem is that this template is generating different output depending > on the size of the containing document. > > > > Here's the pertinent XML fragment: > > > > <note version="8.00"> > > <para version="8.00">blah blah blah.</para> > > <para version="8.00">blah blah blah.</para> > > </note> > > > > The para versions are superfluous, and their presence triggers the > problem, but (a) these documents are not created by me, (b) my code should > cope with superfluous versions anyway, and (c) my code works in smaller > documents. > > > > This is the versiontest template, it should either generate nothing or > output a version string. I've added a few debug lines which I hoped would > clarify the situation (spoiler alert, they don't). > > > > <xsl:template name="versiontest"> > > <!-- > > -- @version is this node's version > > -- $ancvers is the nearest ancestral version, found on node $ancv > > -- the nearest ancestral page break is on node $ancpg > > -- $versdepth is the depth of $ancv from the root > > -- $pgdepth is the depth of $ancpg from the root > > -- We output the version IF @version is different to $ancvers, > > -- OR IF @version matches $ancvers but $versdepth is less than $pgdepth > > -- Note: if versdepth > pgdepth then the version will have appeared > earlier in the page, > > -- if versdepth < pgdepth then it will have appeared on a previous page, > > -- while if versdepth = pgdepth then the version will appear at the top > of the current page > > -- > > > <!-- DEBUG 1 > > <xsl:message select="concat('1 element=', local-name(), ', version=', > @version)" /> > > END DEBUG 1 -- > > > <xsl:variable name="ancv" select=ancestor::*[@version][1]" /> > > <xsl:variable name="ancvers" select="$ancv/@version" /> > > <xsl:variable name="ancpg" select="ancestor::*[local-name() = 'section' > and @break='Y'][1]" /> > > <xsl:variable name="versdepth"> > > <xsl:for-each select="$ancv"> > > <xsl:value-of select="count(ancestor-or-self::*)" /> > > </xsl:for-each> > > </xsl:variable> > > <xsl:variable name="pgdepth"> > > <xsl:for-each select="$ancpg"> > > <xsl:value-of select="count(ancestor-or-self::*)" /> > > </xsl:for-each> > > </xsl:variable> > > <!-- DEBUG 2 > > <xsl:message> > > <xsl:value-of select="concat('2 ancvers=', $ancvers, ', versdepth=', > $versdepth, ', pgdepth=', $pgdepth)" /> > > <xsl:value-of select="concat('[', count(ancestor::*[@version]), ': > ')" /> > > <xsl:for-each select="ancestor::*[@version]"> > > <xsl:value-of select="concat('(', ./@version, ')')" /> > > </xsl:for-each> > > <xsl:text>]</xsl:text> > > </xsl:message> > > END DEBUG 2 -- > > > <xsl:if test="@version != ''"> > > <xsl:if test="@version != $ancvers or not($versdepth > $pgdepth)"> > > <!-- DEBUG 3 > > <xsl:message select="concat('3 output version=', @version)" /> > > END DEBUG 3 C > > <xsl:value-of select="@version" /> > > </xsl:if> > > </xsl:if> > > <xsl:template> > > > > In a smallish document, the versiontest template outputs "8.00" for the > note element and nothing for the para elements. In a large document it > outputs "8.00" for all three elements. > > > > With the debug statements included, the small document generates these > messages > > > > 1 element=note, version=8.00 > > 2 ancvers=, versdepth=, pgdepth=3 [0:] > > 3 output version=8.00 > > 1 element=para, version=8.00 > > 2 ancvers=8.00, versdepth=5, pgdepth=3 [1: (8.00)] > > 1 element=para, version=8.00 > > 2 ancvers=8.00, versdepth=5, pgdepth=3 [1: (8.00)] > > > > I wondered if the larger document might include earlier "versioned" > subtrees that triggered a flaw in my logic, but evidently not. If this was > the cause, there would be more versions listed in the message labelled > DEBUG 2. > > The large document generates these messages > > > > 1 element=note, version=8.00 > > 2 ancvers=, versdepth=, pgdepth=8 [0:] > > 3 output version=8.00 > > 1 element=para, version=8.00 > > 2 ancvers=8.00, versdepth=10, pgdepth=8 [1: (8.00)] > > 3 output version=8.00 > > 1 element=para, version=8.00 > > 2 ancvers=8.00, versdepth=10, pgdepth=8 [1: (8.00)] > > 3 output version=8.00 > > > > I can't see where the tests between DEBUG 2 and DEBUG 3 are going wrong; > certainly if you plug in the values reported in the messages then the > results should be those reported in the smaller documents, not what I'm > actually seeing. > > > > I'm hoping there's a flaw in my logic which is obvious to a more > experienced eye, but I'm afraid I can't see it myself. > > > > You're going to ask for a small failing test case; unfortunately there > isn't one :-( > > > > Cheers > > T > > > > > > > > > > > XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list> > EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/782854> (by > email <>) > -- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- Never fight an inanimate object ------------------------------------- To avoid situations in which you might make mistakes may be the biggest mistake of all ------------------------------------ Quality means doing it right when no one is looking. ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play ------------------------------------- To achieve the impossible dream, try going to sleep. ------------------------------------- Facts do not cease to exist because they are ignored. ------------------------------------- Typing monkeys will write all Shakespeare's works in 200yrs.Will they write all patents, too? :) ------------------------------------- Sanity is madness put to good use. ------------------------------------- I finally figured out the only reason to be alive is to enjoy it.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] test for ancestral attrib, Graydon graydon@xxxx | Thread | Re: [xsl] test for ancestral attrib, Michael Kay mike@xxx |
Re: [xsl] test for ancestral attrib, Graydon graydon@xxxx | Date | Re: [xsl] test for ancestral attrib, Michael Kay mike@xxx |
Month |