Bug #3164
closedjava.lang.ClassCastException: net.sf.saxon.tree.tiny.TinyAttributeImpl cannot be cast to org.w3c.dom.Attr
100%
Description
While writing an extension function using Saxon PE 9.7.0.15 I get this ClassCastException.
public static Node foo(Document commandNode) {
Element command = commandNode.getDocumentElement();
System.out.println("xxx get start");
Attr attributeNode = command.getAttributeNode("width");
System.out.println("xxx get end");
I call the function from XSLT with:
<xsl:value-of select="mycompany:foo($pie)"/>
The output is:
xxx get start
net.sf.saxon.trans.XPathException: Exception thrown by extension function
{public static org.w3c.dom.Node com.mycompany.MyObject.foo(org.w3c.dom.Document)}:
java.lang.ClassCastException: net.sf.saxon.tree.tiny.TinyAttributeImpl cannot be cast to org.w3c.dom.Attr
Within the Saxon source code ElementOverNodeInfo.java method getAttriuteNode line 119 there is:
if (att.getDisplayName().equals(name)) {
return (Attr) att;
}
I think this is where the ClassCastException is occurring. (The stack backtrace does not show where the ClassCastException is occuring, it only shows from my method calling the XSLT processor back up to the main method.)
As far as I can see the TinyAttributeImpl class is supposed to be the Saxon implementation of the Attr interface for the purposes of converting documents to DOM structures when doing extension methods in Java. Yet TinyAttributeImpl does not implement Attr.
Updated by Michael Kay about 7 years ago
You've put this in the Saxon/C project - can you confirm that this is the platform you are using?
I agree with your diagnosis of the problem.
The NodeOverNodeInfo model isn't widely used and it looks as if there aren't enough tests. I wouldn't actually recommend it; the quirks of the DOM interface are such that a mapping from XDM to DOM is always going to have odd behaviour in edge cases. The only real reason for using it is to interface existing code that already uses the DOM, and in those cases the fact that it's a read-only interface might well hit you. Generally you're better off writing your extension functions to the NodeInfo interface.
However, it's a supported interface, so we'll fix this and add a test case.
Updated by Adrian Smith about 7 years ago
Sorry, no, I must have mis-selected, I am using the Java interface to Saxon.
Yes, that's exactly my situation, I have some other existing code which parses certain DOM structures in Java, and it would be convenient to use this code to pass the XML structure passed to the Java extension method.
However, it's not a huge amount of code, I could code it up a second time using the Saxon interfaces.
Thanks for the explanation of the drawbacks and dangers. If I may suggest adding it to the documentation, that would help users (if they don't have existing code) to decide which approach to take. I was looking here http://www.saxonica.com/html/documentation/extensibility/functions/converting-args/converting-node.html for guidance as to how to access the nodes in the XSLT from the Java extension function.
In addition, that documentation states that "saxon9-dom.jar" should be on the classpath. I didn't find that JAR to download anywhere (at least in a recent version). It is not on my classpath, yet (apart from the error described here) it seems to work. Is it possible that this is now bundled with Saxon, meaning those JARs aren't necessary? If so may I recommend removing that line from the documentation.
Thanks for your prompt and helpful replies, as always.
Updated by Michael Kay about 7 years ago
- Project changed from SaxonC to Saxon
- Category changed from Saxon Internal to DOM Interface
- Assignee changed from O'Neil Delpratt to Debbie Lockett
- Applies to branch 9.7, 9.8 added
Moved to the Saxon project.
Updated by Debbie Lockett about 7 years ago
Unit test added (for 9.7 and 9.8) to reproduce the problem (in jaxptest/DOMTest.java).
Updated by Debbie Lockett about 7 years ago
In ElementOverNodeInfo.getAttributeNode(), the TinyAttributeImpl attr should be wrapped before being returned, to give an AttrOverNodeInfo which does implement Attr.
Fix committed on 9.7 and 9.8 branches.
Still to do: suggested documentation updates.
Updated by Debbie Lockett about 7 years ago
- Status changed from New to Resolved
- Fix Committed on Branch 9.7, 9.8 added
Documentation now updated, to remove references to old jars, and add a comment as suggested: see http://saxonica.com/documentation/index.html#!extensibility/functions/converting-args/converting-node
Changes committed to 9.7 and 9.8 branches, and online 9.7 documentation (XML and HTML versions).
Updated by O'Neil Delpratt about 7 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 9.7.0.18 added
Bug fix applied in the Saxon 9.7.0.18 maintenance release.
Updated by O'Neil Delpratt almost 7 years ago
- Fix Committed on Branch trunk added
- Fix Committed on Branch deleted (
9.8)
Please register to edit this issue