Xerces ElementNodes / DOMEnvelope / bug?
Added by Anonymous over 17 years ago
Legacy ID: #4421664 Legacy Poster: Bertrand Mirat (bemi)
Hi, using saxon8-dom.jar and saxon8.8, I stumbled on something that I think may be a bug. What I have is, 1) a method in some class that returns an Element created using JAXP DocumentBuilderFactory mechanism (this ends up for me in Xerces' DOM implementation) : public class ElementCreator { /* This method returns an org.apache.xerces.dom.ElementImpl */ public static newElement () throws DOMException, ParserConfigurationException { return DocumentBuilderFactory.newInstance() .newDocumentBuilder().newDocument() .createElement("e"); } } 2) this method will be used from within an XQuery using a 'test' prefix : // [...] basic initialization code staticContext.declarePassiveNamespace("test", "java:ElementCreator", false); 3) call the java method from a Saxon XQuery using the 'test' prefix : xquery = staticContext.compileQuery ("test:newElement"); ...I would expect a result list with one item when evaluating : xquery.evaluate(); ..but what I get is an empty list. But note, if I add a child Node -say, a Text- to the Element before returning it, the XQuery evaluation result is as expected : a list with one element. I tracked this unexpected behaviour down to the method : DOMEnvelope.convertObjectToXPathValue(Object object) { if (object instanceof NodeList) { // [...] loop over the Nodes from the NodeList, // [...] returning null if one is not an instance of NodeOverNodeInfo return new SequenceExtent(nodes); } ...and I found that, Xerces' ElementImpl being also a NodeList, if it has no child, we end up returning the SequenceExtent with no node inside => empty result list. But if the ElementImpl has a child, this method returns null because the Element's child is not a NodeOverNodeInfo ; and the Element is then later wrapped into a NodeWrapper by DOMObjectModel (this happens at the end of Value.convertToBestFit) => one result list as expected. Is this a bug? Shouldn't the first line of DOMEnvelope.convertObjectToXPathValue(Object object) be more similar to the first line of DOMObjectModel.convertObjectToXPathValue(Object object) , that is, if (object instanceof NodeList && !(object instanceof Node)) { ..?
Replies (2)
RE: Xerces ElementNodes / DOMEnvelope / bug? - Added by Anonymous over 17 years ago
Legacy ID: #4421703 Legacy Poster: Michael Kay (mhkay)
I think this is a known problem, and it was fixed in Saxon 8.9 though not quite in the way you suggest (your fix would prevent some useful uses of NodeList). I don't think it can strictly be described as a "bug", at least, not a bug in Saxon. There are situations with cross-language interfaces where you have to rely on dynamic type information, and if your function returns an object that says it is a NodeList then the caller is entitled to treat it as a NodeList. The fact that most users creating an Element and returning it from a function would not realise that the object is a NodeList (let alone a NodeList whose members are the children of the element) suggests that Xerces have a rather contorted data model, and this is going to affect its ability to work well with other products. There was an even worse example I encountered in Oracle's DOM, where a document node implements the Element interface. This is not a good design pattern.
RE: Xerces ElementNodes / DOMEnvelope / bug? - Added by Anonymous over 17 years ago
Legacy ID: #4422818 Legacy Poster: Bertrand Mirat (bemi)
Thanks for the -fast!- answer! I can work with this, returning a NodeInfo instead of Xerces' ElementImpl, but I hesitate between two ways to do this -what I want is a NodeWrapper around the newly-created Document root Element: return new DOMObjectModel().unravel( new DOMSource(elementImpl.getOwnerDocument().getDocumentElement()), new Configuration()); ..or.. return new DocumentWrapper( elementImpl.getOwnerDocument(), elementImpl.getOwnerDocument().getBaseURI(), new Configuration()).wrap(elementImpl.getOwnerDocument().getDocumentElement()); I wonder which syntax would be more appropriate... Or would there be a better way to do this?
Please register to reply