Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

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 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/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

Michael Kay
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

On 10 Jul 2015, at 04:33, Wolfhart Totschnig <[hidden email]> 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/
[hidden email]
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/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

Wolfhart Totschnig
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 <[hidden email]> 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

On 10 Jul 2015, at 04:33, Wolfhart Totschnig <[hidden email]> 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/
[hidden email]
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/
[hidden email]
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/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

Paul Mensonides
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>


From: "Wolfhart Totschnig" <[hidden email]>
To: "Mailing list for the SAXON XSLT and XQuery processor" <[hidden email]>
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 <[hidden email]> 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

On 10 Jul 2015, at 04:33, Wolfhart Totschnig <[hidden email]> 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/
[hidden email]
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/
[hidden email]
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/
[hidden email]
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/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

Michael Kay
In reply to this post by Wolfhart Totschnig

> On 11 Jul 2015, at 03:08, Wolfhart Totschnig <[hidden email]> wrote:
>
> 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.

You could experiment with variations like http://xxxxx vs HTTP://xxxxx, or a/b/c vs a/./b/c, or a/b/c vs %61/b/c. I don’t offer any guarantees, and even if it works on one release it might not work on the next.

Michael Kay
------------------------------------------------------------------------------
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/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help 
Reply | Threaded
Open this post in threaded view
|

Re: Error when trying to overwrite another document: "Cannot write to a URI that has already been read"

Wolfhart Totschnig
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

------------------------------------------------------------------------------
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/
[hidden email]
https://lists.sourceforge.net/lists/listinfo/saxon-help