xsl:result-document href-attribute: ?select=//div and alike result in ClassCastException
I was attempting to address elements without id attributes for replacement with xsl:result-document using the select path feature. I was attempting to use generic paths like //[generate-id() = $id], and ///, but that didn't seem to work. Then I tried something like //div, which points to an existing element in the HTML dom. But Saxon-CE fails silently in Chrome, IE 9 shows a ClassCastException in an overlay, FF 9 shows the same error in the Firebug console.
#1 Updated by Community Admin over 9 years ago
- Assignee set to Philip Fearon
I'm afraid I'm still unable to reproduce this issue with the ClassCastException. If this were simply a problem related to the href of xsl:result-document, I wouldn't expect to see the error you're getting. The exception you're seing is only being handled at the top level, so I can't event tell whether this is a static (compile-time) or dynamic error.
My suspicion is that the exception occurs at run-time during the attempt to update the HTML DOM, but that's a bit of a wild guess until I have some more information.
Could you please send a simple example that reproduces this issue, either as an attachment on this issue thread or direct to myself at: email@example.com
#2 Updated by Philip Fearon over 9 years ago
Looking at the included sample files the main problem here is that
there is an issue with the approach used in the XSLT and the resulting
error message is extremely unhelpful.
In the provided sample HTML page, the <script> element has a
data-source attribute value set to a URL that happens to be the same
as the host HTML page, which happens to be well-formed XML.
So, this file is loaded as XML by Saxon-CE using the usual
XMLHTTPRequest object and the XSLT transform commences on this file.
The issue is that when processing the href attribute of the
xsl:result-document document, the baseURI of the context node and that
of the document object are compared. Because these are found to be
equal, Saxon-CE wrongly assumes that the context node is within the
DOM and attempts to proceed with modifying some part of the context
node instead of the DOM.
To prevent this from happening in future Saxon-CE releases I'll add a
check on the data-source attribute in the <script> element, if the URL
is the same as that of the host page a fatal error will be raised.
To acheive the same effect as the supplied sample the following
changes could be made to the two sample files:
- HTML File
1.1. Remove the data-source attribute from the <script> element
1.2. Add a data-initial-template attribute with value 'main' to the<script> element 2. XSLT File --------- 2.1. Remove the match="/" attribute from the entry template and add a name="main" attribute instead 2.2. Modify the select="*" attribute in the apply-templates instruction (within the entry template) to be select="ixsl:page()/*" These modified sample files are attached. The key part to this approach is the ixsl:page() extension function. This returns the document node of the host HTML page, so ixsl:page()/* will return the html element, apply-templates can then be called on this so that HTML child elements can be processed. In this case, because the context node is always part of the DOM (which is read/write) it can be exploited safely in result-document href attributes. It's likely of course that there'll be other cases where you need to use xsl:result-document but when the context node is from an XML file (specified in the data-source). In this case, you can either: i) use an absolute location in your href XPath (e.g. //div/p[@class='new']) or 2) wrap the result-document instruction within an xsl:for-each instruction where the ixsl:page() function is used in the select attribute to set the context, (eg.
Please register to edit this issue