Discussion:
[Exist-open] xsl:copy-of with attribute : exerr:ERROR, Exception while transforming node: An attribute node (attr) cannot be, created after a child of the containing element
Ron Van den Branden
2017-06-26 14:29:59 UTC
Permalink
Hi Rémi,

This seems very similar to a long-standing bug described at
https://github.com/eXist-db/exist/issues/214. I think the problem lies
in how the transform:transform() function processes nodes that have been
imported in an XSLT stylesheet via the doc() function. My earlier report
dates back from eXist-2.1, but I've tested again and can confirm that it
still holds (eXist-3.2.0).

In your example XSLT stylesheet, if you replace the <xsl:copy-of/>
instruct ion with an identity transformation (using
<xsl:apply-templates/>), it will behave as expected:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="/">
<xsl:apply-templates select="doc('insert.xml')" mode="copy"/>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Of course, this is only a workaround for what I believe is a bug in
eXist (the XSLT transformation works without problems in Saxon), which
is triggered by following conditions:
-the XSLT stylesheet called with transform:transform() is stored in
the db (the same stylesheet works when it is stored on the file system)
-the XSLT stylesheet:
-imports an XML tree via the doc() function
-copies (parts of) that imported XML tree directly via
<xsl:copy-of/>

I have reworked the original example of that Github issue to an eXist
app (see attachment). When installed, the bug (and some indications for
isolating it) can be tested at
http://localhost:8080/exist/apps/xslt-doc-copy-test/. I'll try and see
if I can add this to the original bug report on Github (and possibly
clarify that report where needed).

Best,

Ron
Rémi Koutchérawy
2017-06-26 19:51:30 UTC
Permalink
This seems very similar to a long-standing bug described at https://github.com/eXist-db/exist/issues/214. I think the problem lies in how the transform:transform() function processes nodes that have been imported in an XSLT stylesheet via the doc() function.
Yes, you are right thank you !

On my side I imported Saxon sources along with Exist and tried to debug at Java level.
https://github.com/RemiKoutcherawy/exist/blob/develop/test/src/org/exist/xquery/XSLCopyOfTest.java (one test pass the second fails)

In the copy process Saxon decodes the first attribute then finds and reads another one !?
Trying to set an attribute on an attribute makes it throw an exception.

The problem lies between Exist and Saxon.
I didn't find where Exist serializes the XML, the process is a pipe, the XML nodes and attributes
are sent one after the other in a loop involving both Saxon and Exist.

Maybe someone can pinpoint where Exist is building the DOM send to Saxon ?

Remi

Loading...