Re: [xsl] test for ancestral attribute returning variant results

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