Discussion:
[saxon] Error when trying to overwrite another document: "Cannot write to a URI that has already been read"
Wolfhart Totschnig
2015-07-10 03:33:39 UTC
Permalink
Hi,

In an XSLT transformation, I would like to check whether some information
in the source document is also contained in another document and, if not,
add the information to that other document (i.e., modify the other
document). But I get the following error message from saxon9he: "Cannot
write to a URI that has already been read". A minimal example would be
this:

<xsl:template match="foo">
<xsl:if test="not(document('bar.xml',.)/foo = .)">
<xsl:result-document href="bar.xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:if>
</xsl:template>

The few discussions of the given error message that I can find refer to
cases in which the href attribute of the result-document instruction
designates the source document. I understand that it is not possible to
overwrite the source document during a transformation. But that's not what
I am trying to do -- I am trying to overwrite another document. And I don't
understand why that should not be possible, and so I am wondering why I am
receiving the error message.

Thank you in advance for your help.

Best regards,
Wolfhart
Michael Kay
2015-07-10 08:01:17 UTC
Permalink
Saxon is implementing a rule in the specification here:

[ERR XTDE1500] <> It is a dynamic error <https://www.w3.org/XML/Group/qtspecs/specifications/xslt-30/html/Overview-diff.html#dt-dynamic-error> for a stylesheet <https://www.w3.org/XML/Group/qtspecs/specifications/xslt-30/html/Overview-diff.html#dt-stylesheet> to write to an external resource and read from the same resource during a single transformation, if the same absolute URI is used to access the resource in both cases.

The reason for the rule is that the order of evaluation is (in general) undefined. In your particular case the order is well-defined: the test expression of xsl:if must necessarily be evaluated before the body of the xsl:if. But in the general case, the compiler could change the order of execution so the write action happens before the read.

The easiest way to get around this restriction is by writing a URIResolver or OutputURIResolver that redirects the URIs, in such a way that Saxon doesn’t know that two different URIs are actually referring to the same thing. You might even be able to contrive two different ways of writing the URI that Saxon fails to recognise as equivalent.

Michael Kay
Saxonica
Post by Wolfhart Totschnig
Hi,
<xsl:template match="foo">
<xsl:if test="not(document('bar.xml',.)/foo = .)">
<xsl:result-document href="bar.xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:if>
</xsl:template>
The few discussions of the given error message that I can find refer to cases in which the href attribute of the result-document instruction designates the source document. I understand that it is not possible to overwrite the source document during a transformation. But that's not what I am trying to do -- I am trying to overwrite another document. And I don't understand why that should not be possible, and so I am wondering why I am receiving the error message.
Thank you in advance for your help.
Best regards,
Wolfhart
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
https://lists.sourceforge.net/lists/listinfo/saxon-help
Wolfhart Totschnig
2015-07-11 02:08:56 UTC
Permalink
Dear Michael,

Thank you for the reply! Writing a URIResolver is unfortunately beyond my
capabilities -- if I understand correctly, the URIResolver would have to be
written in Java, and I don't know Java -- so I would like to ask you what
you have in mind with "two different ways of writing the URI that Saxon
fails to recognise as equivalent". The only thing that I could think of was
writing the URI once as a relative and once as an absolute URI, but that
does not help. I am running on Linux (Ubuntu), in case that's relevant.

Thanks again,
Wolfhart
[ERR XTDE1500] It is a dynamic error
<https://www.w3.org/XML/Group/qtspecs/specifications/xslt-30/html/Overview-diff.html#dt-dynamic-error> for
a stylesheet
<https://www.w3.org/XML/Group/qtspecs/specifications/xslt-30/html/Overview-diff.html#dt-stylesheet> to
write to an external resource and read from the same resource during a
single transformation, if the same absolute URI is used to access the
resource in both cases.
The reason for the rule is that the order of evaluation is (in general)
undefined. In your particular case the order is well-defined: the test
expression of xsl:if must necessarily be evaluated before the body of the
xsl:if. But in the general case, the compiler could change the order of
execution so the write action happens before the read.
The easiest way to get around this restriction is by writing a URIResolver
or OutputURIResolver that redirects the URIs, in such a way that Saxon
doesn’t know that two different URIs are actually referring to the same
thing. You might even be able to contrive two different ways of writing the
URI that Saxon fails to recognise as equivalent.
Michael Kay
Saxonica
On 10 Jul 2015, at 04:33, Wolfhart Totschnig <
Hi,
In an XSLT transformation, I would like to check whether some information
in the source document is also contained in another document and, if not,
add the information to that other document (i.e., modify the other
document). But I get the following error message from saxon9he: "Cannot
write to a URI that has already been read". A minimal example would be
<xsl:template match="foo">
<xsl:if test="not(document('bar.xml',.)/foo = .)">
<xsl:result-document href="bar.xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:if>
</xsl:template>
The few discussions of the given error message that I can find refer to
cases in which the href attribute of the result-document instruction
designates the source document. I understand that it is not possible to
overwrite the source document during a transformation. But that's not what
I am trying to do -- I am trying to overwrite another document. And I don't
understand why that should not be possible, and so I am wondering why I am
receiving the error message.
Thank you in advance for your help.
Best regards,
Wolfhart
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
https://lists.sourceforge.net/lists/listinfo/saxon-help
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
https://lists.sourceforge.net/lists/listinfo/saxon-help
p***@comcast.net
2015-07-11 05:07:15 UTC
Permalink
You can probably use a symlink to do it.

ln -s bar.xml baz.xml

<xsl:template match="foo">
<xsl:if test="not(document('bar.xml',.)/foo = .)">
<xsl:result-document href=" baz.xml ">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:if>
</xsl:template>

----- Original Message -----

From: "Wolfhart Totschnig" <***@u.northwestern.edu>
To: "Mailing list for the SAXON XSLT and XQuery processor" <saxon-***@lists.sourceforge.net>
Sent: Friday, July 10, 2015 7:08:56 PM
Subject: Re: [saxon] Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

Dear Michael,

Thank you for the reply! Writing a URIResolver is unfortunately beyond my capabilities -- if I understand correctly, the URIResolver would have to be written in Java, and I don't know Java -- so I would like to ask you what you have in mind with "two different ways of writing the URI that Saxon fails to recognise as equivalent". The only thing that I could think of was writing the URI once as a relative and once as an absolute URI, but that does not help. I am running on Linux (Ubuntu), in case that's relevant.

Thanks again,
Wolfhart

On Fri, Jul 10, 2015 at 10:01 AM, Michael Kay < ***@saxonica.com > wrote:



Saxon is implementing a rule in the specification here:

[ERR XTDE1500] It is a dynamic error for a stylesheet to write to an external resource and read from the same resource during a single transformation, if the same absolute URI is used to access the resource in both cases .

The reason for the rule is that the order of evaluation is (in general) undefined. In your particular case the order is well-defined: the test expression of xsl:if must necessarily be evaluated before the body of the xsl:if. But in the general case, the compiler could change the order of execution so the write action happens before the read.

The easiest way to get around this restriction is by writing a URIResolver or OutputURIResolver that redirects the URIs, in such a way that Saxon doesn’t know that two different URIs are actually referring to the same thing. You might even be able to contrive two different ways of writing the URI that Saxon fails to recognise as equivalent.

Michael Kay
Saxonica


<blockquote>

On 10 Jul 2015, at 04:33, Wolfhart Totschnig < ***@u.northwestern.edu > wrote:

Hi,

In an XSLT transformation, I would like to check whether some information in the source document is also contained in another document and, if not, add the information to that other document (i.e., modify the other document). But I get the following error message from saxon9he: "Cannot write to a URI that has already been read". A minimal example would be this:

<xsl:template match="foo">
<xsl:if test="not(document('bar.xml',.)/foo = .)">
<xsl:result-document href="bar.xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:if>
</xsl:template>

The few discussions of the given error message that I can find refer to cases in which the href attribute of the result-document instruction designates the source document. I understand that it is not possible to overwrite the source document during a transformation. But that's not what I am trying to do -- I am trying to overwrite another document. And I don't understand why that should not be possible, and so I am wondering why I am receiving the error message.

Thank you in advance for your help.

Best regards,
Wolfhart
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
saxon-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help





------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
saxon-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help

</blockquote>



------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
saxon-help mailing list archived at http://saxon.markmail.org/
saxon-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/saxon-help
Michael Kay
2015-07-11 08:02:10 UTC
Permalink
This post might be inappropriate. Click to display it.
Wolfhart Totschnig
2015-07-12 03:53:10 UTC
Permalink
Post by Michael Kay
a/b/c vs a/./b/c, or a/b/c vs %61/b/c
Thanks again, Michael! The first method does the trick for me (but not the
second).
Wolfhart

Loading...