https://saxonica.plan.io/https://saxonica.plan.io/favicon.ico2019-05-14T09:37:33ZSaxonica Developer CommunitySaxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135762019-05-14T09:37:33ZMichael Kaymike@saxonica.com
<ul></ul><p>I've started by running this on 9.9 and I get a different error:</p>
<pre><code>Error in xsl:copy-of/@select on line 10 column 29 of Relationship_EBI.xsl:
XPDY0002: The context item is absent
at procedure setEnrichedMessage on line 9 of Relationship_EBI.xsl:
invoked by global xsl:variable
In template rule with match="/" on line 13 of Relationship_EBI.xsl
</code></pre>
<p>This is because the global variable contains a reference to the global context item ".", and <code>StreamingTransformerFactory</code> explicitly doesn't allow that: the Javadoc for<code> StreamingTransformerFactory</code> states: "Because it is designed for streaming, the source document does not become the global context item (specifically, if a global variable references the value of the context item ".", a dynamic error XPDY0002 occurs)."</p>
<p>So on 9.9, this is working as designed.</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135772019-05-14T10:01:48ZMichael Kaymike@saxonica.com
<ul></ul><p>I have reproduced the error you are seeing on the 9.8 branch.</p>
<p>Although the Javadoc for <code>StreamingTransformerImpl</code> in 9.8 states the same restriction on use of the context item as in 9.9, it does not seem to be enforced as rigorously; in fact, on the non-streaming path being executed, the context item is explicitly set to the source node of the transformation. And in fact, this doesn't seem to be related to the failure, because we get the same failure if we substitute an EnterpriseTransformerFactory for the StreamingTransformerFactory.</p>
<p>What actually seems to be happening here is that the input document contains whitespace text nodes. The element causing the failure is:</p>
<pre><code><test>
<a>12
3</a>
<b>456</b>
</test>
</code></pre>
<p>which fails because text() selects more than one child text node (there are three whitespace text node children).</p>
<p>The stylesheet specifies xsl:strip-space so this shouldn't be happening</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135782019-05-14T10:04:22ZStefan Fritz
<ul></ul><p>The idea of the customer was to replace &#xA and &#xD with a semicolon.</p>
<p>Their main argument is that this works fine on commandline and not in the way we apply the XSL.</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135792019-05-14T10:25:36ZMichael Kaymike@saxonica.com
<ul></ul><p>There seems to be a clear error on the 9.8 branch that has been corrected in 9.9. In Controller.makeSourceTree(), 9.8 has</p>
<pre><code>if (config.isStripsAllWhiteSpace() || isStylesheetContainingStripSpace() ||
validationMode == Validation.STRICT || validationMode == Validation.LAX) {
Stripper stripper = makeStripper(sourceBuilder);
spaceStrippingRule = stripper.getSpaceStrippingRule();
}
</code></pre>
<p>which has been changed in 9.9 to</p>
<pre><code>if (config.isStripsAllWhiteSpace() || isStylesheetContainingStripSpace() ||
validationMode == Validation.STRICT || validationMode == Validation.LAX) {
r = makeStripper(sourceBuilder);
spaceStrippingRule = getSpaceStrippingRule();
}
</code></pre>
<p>So 9.8 is creating the stripper (which does the whitespace stripping) but isn't inserting it into the document-building pipeline.</p>
<p>Looking at the change history, 9.9 has had this change since it was first released.</p>
<p>The error appears to have been introduced into the 9.8 branch with commit 2588, which was attempting to fix bug 3885, and first hit the field with maintenance release 9.8.0.15.</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135802019-05-14T10:34:11ZMichael Kaymike@saxonica.com
<ul><li><strong>Category</strong> set to <i>JAXP Java API</i></li><li><strong>Status</strong> changed from <i>New</i> to <i>In Progress</i></li><li><strong>Assignee</strong> set to <i>Michael Kay</i></li><li><strong>Applies to branch</strong> <i>9.8</i> added</li><li><strong>Fix Committed on Branch</strong> <i>9.8</i> added</li></ul><p>Confirmed that if we change the 9.8 code to be the same as 9.9, this test case works.</p>
<p>So it looks as if we might have to plan for another maintenance release on the 9.8 branch (which means looking at what other patches are also outstanding).</p>
<p>Meanwhile, I have committed the change.</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135812019-05-14T10:38:30ZMichael Kaymike@saxonica.com
<ul></ul><p>Also confirmed that the test works on 9.9 if we change the StreamingTransformerFactory to an EnterpriseTransformerFactory.</p>
<p>(I also had to delete inactive code using an old MessageEmitter interface to get it to compile under 9.9)</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135822019-05-14T10:59:43ZMichael Kaymike@saxonica.com
<ul></ul><p>Confirmed also that the method in question (<code>Controller.makeSourceTree()</code>) is not being used when the transformation is run from the command line. For some reason the command line has its own way of doing the source document building, which differs from the code used by JAXP.</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135832019-05-14T13:07:51ZStefan Fritz
<ul></ul><p>As workaround for our customer: Is there a XSL level change that we can do to get this XSL working the way it does on commandline?</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135852019-05-14T13:39:17ZMichael Kaymike@saxonica.com
<ul></ul><p>I think at the XSLT level the simplest is probably to strip whitespace text nodes explicitly:</p>
<pre><code><xsl:mode name="strip-space" on-no-match="shallow-copy"/>
<xsl:template match="text()[.='']" mode="strip-space"/>
<xsl:function name="f:strip-space" as="document-node()">
<xsl:param name="in" as="document-node()"/>
<xsl:apply-templates select="$in" mode="strip-space"/.
<xsl:function>
</code></pre> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135862019-05-14T14:07:31ZStefan Fritz
<ul></ul><p>Sorry I don't get how to use this.
The function is not invoked from what I see.
And the requirement is to replace the
and
whitespace characters with ';' (semicolon).
This is part of the Cleanup.xsl</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135872019-05-14T15:22:32ZMichael Kaymike@saxonica.com
<ul></ul><p>You're currently doing:</p>
<pre><code> <!-- Perform Enrichments -->
<xsl:variable name="setEnrichedMessage">
<xsl:copy-of select="." />
</xsl:variable>
<xsl:template match="/">
<!-- Perform Clean Up -->
<xsl:apply-templates select="$setEnrichedMessage" mode="CleanUp"/>
</xsl:template>
</code></pre>
<p>I'm not sure I understand the logic of this (why is setEnrichedMessage a copy of the input document, why can't it use the original? Perhaps there's some overriding stylesheet somewhere?) but as written you could simply change the logic to</p>
<pre><code><xsl:apply-templates select="f:strip-space(.)" mode="CleanUp"/>
</code></pre>
<p>or you could change the variable to</p>
<pre><code> <xsl:variable name="setEnrichedMessage">
<xsl:apply-templates select="." mode="strip-space" />
</xsl:variable>
</code></pre> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=135882019-05-14T15:23:56ZMartin Honnenmartin.honnen@gmx.de
<ul></ul><p>If the aim is to replace those two characters in text nodes then I would simply match on <code>text()</code> and perform the replacement e.g. instead of</p>
<pre><code class="xml syntaxhl" data-language="xml"> <span class="nt"><xsl:template</span> <span class="na">match=</span><span class="s">"*[text()[contains(.,'&#xA;') or contains(.,'&#xD;')]]"</span> <span class="na">mode=</span><span class="s">"CleanUp"</span><span class="nt">></span>
<span class="nt"><xsl:copy></span>
<span class="nt"><xsl:apply-templates</span> <span class="na">select=</span><span class="s">"@*"</span> <span class="na">mode=</span><span class="s">"CleanUp"</span><span class="nt">/></span>
<span class="nt"><xsl:value-of</span> <span class="na">select=</span><span class="s">"replace(replace(text(),'&#xA;',';'),'&#xD;',';')"</span><span class="nt">/></span>
<span class="nt"></xsl:copy></span>
<span class="nt"></xsl:template></span>
</code></pre>
<p>you could simply use</p>
<pre><code class="xml syntaxhl" data-language="xml"> <span class="nt"><xsl:template</span> <span class="na">match=</span><span class="s">"text()"</span> <span class="na">mode=</span><span class="s">"CleanUp"</span><span class="nt">></span>
<span class="nt"><xsl:value-of</span> <span class="na">select=</span><span class="s">"replace(replace(.,'&#xA;',';'),'&#xD;',';')"</span><span class="nt">/></span>
<span class="nt"></xsl:template></span>
</code></pre>
<p>As you already have an identity transformation template the element node copying is taken care of.</p> Saxon - Bug #4219: StreamingTransformerImpl fails to run xsl but same xsl works on commandlinehttps://saxonica.plan.io/issues/4219?journal_id=136732019-06-05T16:21:25ZMichael Kaymike@saxonica.com
<ul><li><strong>Status</strong> changed from <i>In Progress</i> to <i>Resolved</i></li></ul><p>I'm going to mark this resolved, which is the status we use when we believe we have identified the fault and committed a patch (the status moves to "Closed" when we put out a maintenance release containing the patch).</p>
<p>There's no certainty that there will be another 9.8 maintenance release. I think I've given you a workaround that will keep you going; if that's not the case and this patch is urgently required then please let us know.</p>