https://saxonica.plan.io/https://saxonica.plan.io/favicon.ico2021-07-05T23:23:06ZSaxonica Developer CommunitySaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181322021-07-05T23:23:06ZMartynas Jusevicius
<ul></ul><p>Using Saxon 2.2.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181342021-07-06T07:15:37ZMartin Honnenmartin.honnen@gmx.de
<ul></ul><p>I think the problem might simply be that the index for a key declaration is built-once but is not later updated when the document is changed. At <a href="https://martin-honnen.github.io/xslt/2021/saxon-js-key-test-ee1.html" class="external">https://martin-honnen.github.io/xslt/2021/saxon-js-key-test-ee1.html</a> there is an initial value for the key call but it remains constant while a direct attribute based selection does take the actual state of the tree into account.
Solely a guess, however.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181352021-07-06T07:17:22ZMartin Honnenmartin.honnen@gmx.de
<ul></ul><p>Note that you seem to use Saxon JS 2.1 despite your statement you tested with 2.2. But I don't think that matters.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181362021-07-06T07:37:23ZMartynas Jusevicius
<ul></ul><p>You're right, I was still generating SEF with 2.1. Now it should be 2.2 for real.</p>
<p>The key thing is not great then. If ID lookups can work, I would keys expect to work as well. But lets see what Saxonica says :)</p>
<p>As a workaround, I'm trying to call the key on <code>$xhtml</code> to get IDs of those elements and then use <code>id()</code> on <code>ixsl:page()</code>.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181372021-07-06T07:49:08ZMartynas Jusevicius
<ul></ul><p>The strange thing was, unless I'm mistaken, that if I inlined the <code>some-template</code> code directly into the <code>ixsl:onclick</code> handler, it worked as expected. But I don't want to touch it anymore :)</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181382021-07-06T08:26:46ZMichael Kaymike@saxonica.com
<ul></ul><p>I do recall a known issue/restriction in this area, but I'm having trouble finding any documentation.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181392021-07-06T08:36:34ZMartin Honnenmartin.honnen@gmx.de
<ul></ul><p>For accumulators on HTML documents there is a warning: "Accumulator values are attached to DOM nodes in situ. This means a DOM node can't have different values for the same accumulator name in different transformations. This is likely to be a permanent restriction. Advice for users: do not use accumulators on the HTML document, because it is mutable.".</p>
<p>Perhaps the same holds for keys?</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181452021-07-08T14:14:14ZDebbie Lockettdebbie@saxonica.com
<ul></ul><p>Martin is right that the key index is only built once, but since the HTML page is mutable this is not necessarily good enough. As Mike and Martin have noted, this restriction is unfortunately not documented. So in the short-term, we need to update the documentation to include a warning about the use of keys for nodes in the HTML page.</p>
<p>In the long term, we should improve the implementation so that such keys are actually usable. The key indexes should be rebuilt if the HTML page has any (relevant) changes.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181462021-07-08T14:19:46ZMartynas Jusevicius
<ul></ul><p>Makes sense. <a href="https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver" class="external"><code>MutationObserver</code></a> could be useful for tracking DOM changes.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=181472021-07-08T14:24:33ZDebbie Lockettdebbie@saxonica.com
<ul><li><strong>Category</strong> set to <i>XSLT Conformance</i></li><li><strong>Status</strong> changed from <i>New</i> to <i>In Progress</i></li><li><strong>Assignee</strong> set to <i>Debbie Lockett</i></li></ul><p>Selenium test <code>iss5036</code> added to our test suite (based on Martin's sample test).</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=183122021-08-18T12:09:51ZDebbie Lockettdebbie@saxonica.com
<ul></ul><p>Warning added to the documentation, under <code>conformance/xslt30</code> (which will be updated online with the next maintenance release).</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=199022022-03-09T20:11:37ZMartynas Jusevicius
<ul></ul><p>Any news on this?</p>
<p>How about a new instruction that would rebuild the keys? For example: <code><ixsl:refresh-key name="lines-by-start"/></code></p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=199042022-03-10T09:21:35ZMartynas Jusevicius
<ul></ul><p>I had to get rid of <code>key()</code> usages because of this issue and replace them with <code>ixsl:page()//...</code> lookup. Rendering an interactive SVG graph with hundreds of nodes, the performance degradation is clearly noticeable :(</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=203352022-04-08T16:30:39ZMichael Kaymike@saxonica.com
<ul></ul><p>My inclination is to resolve this by having the key() function do a straight search (without using indexes) when the target document is mutable. The HTML page is rarely going to be so big that it's going to make a big difference.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=203362022-04-08T18:23:21ZMartynas Jusevicius
<ul></ul><p>Respectfully, that sounds the worst option of all 3 (the other two being automatic key refresh and explicit refresh instruction). Is it so hard to refresh them keys?</p>
<p>In our case all documents are mutable, because navigation is done by Saxon-JS loading and injecting document fragments into DOM.</p>
<p>As mentioned above, I've replaced <code>key()</code> lookup with <code>//</code> on an SVG document with hundreds of elements, and the slowdown was noticeable.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=204862022-05-06T14:59:16ZNorm Tovey-Walsh
<ul><li><strong>Status</strong> changed from <i>In Progress</i> to <i>Resolved</i></li><li><strong>Applies to JS Branch</strong> <i>Trunk</i> added</li><li><strong>Fix Committed on JS Branch</strong> <i>2, Trunk</i> added</li></ul><p>After some investigation, we concluded that it was easy to force the indexes to be rebuilt after a page change. Starting with the Saxon 2.4 maintenance release, any page change will automatically invalidate the indexes, forcing a rebuild before the next use of the <code>fn:key()</code> function (or other functions that use the indexes).</p>
<p>There’s no performance cost associated with invalidating the indexes. But there is, naturally, a performance cost associated with rebuilding them.</p>
<p>In the (we expect, unlikely) event that you have an application that makes heavy use of indexes, and updates the page, and where the updates are known not to change any of the indexed values, you can disable the behavior.</p>
<p>There is a new API, setConfigurationProperty on the SaxonJS object. If you call:</p>
<pre><code>SaxonJS.setConfigurationProperty('autoResetIndexes', false);
</code></pre>
<p>then automatic invalidation of indexes will be disabled. At that point, it becomes the application’s responsibility to reset them. There’s a function on the SaxonJS object to reset the indexes. There’s no ixsl: function in Saxon 2.4, so you have to do it indirectly:</p>
<pre><code> <xsl:sequence
select="ixsl:eval('(function(doc) { SaxonJS.resetIndexes(doc) })')
=> ixsl:apply([ixsl:page()])"/>
</code></pre>
<p>After the indexes have been reset, any attempt to use an index-backed function will rebuild them.</p> SaxonJS - Bug #5036: key() doesn't work on ixsl:page() after ixsl:replace-content?https://saxonica.plan.io/issues/5036?journal_id=205402022-05-12T13:22:37ZDebbie Lockettdebbie@saxonica.com
<ul><li><strong>Status</strong> changed from <i>Resolved</i> to <i>Closed</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>100</i></li><li><strong>Fixed in JS Release</strong> set to <i>SaxonJS 2.4</i></li></ul><p>Bug fix applied in the SaxonJS 2.4 maintenance release.</p>