Project

Profile

Help

XdmNode to org.w3c.dom.Node

Added by Dimitrios Iakovidis over 6 years ago

Hello, I am fairly new to Saxon. I have a problem trying to convert xdmNode to org.w3c.dom.Node. I found this post https://stackoverflow.com/questions/42790868/saxon-convert-xdmnode-to-org-w3c-dom-node , and regarding Michael Kay's answer i tried to run a identity transformation, based on saxon-resources examples (JAXPexamples.java) with a supplied identity transformation xsl. I am not sure if that is meant by 'identity transformation'.

... // Create a transform factory instance. TransformerFactory tfactory = TransformerFactory.newInstance();

// Create a transformer for the stylesheet.
Transformer transformer =
  tfactory.newTransformer(new StreamSource(xsl));
// Transform the source XML

transformer.transform(inputNode.asSource(), new DOMResult(extra)); ...

Resulting to this:

java.lang.IllegalArgumentException: Externally supplied NodeInfo belongs to the wrong Configuration at net.sf.saxon.Configuration.unravel(Configuration.java:3083) at net.sf.saxon.Controller.prepareInputTree(Controller.java:1963) at net.sf.saxon.Controller.transform(Controller.java:1852) ..

NOTE: ** inputNode is the result of a calabash invocation, a XdmNode holding a TinyDocumntTreeImpl that contains my xml content. Also i am using saxon he 9.5.1.-8. **inputNode.getExternalNode() returns null.

I think i am missing something bigger here, so i would appreciate any help.


Replies (2)

RE: XdmNode to org.w3c.dom.Node - Added by Michael Kay over 6 years ago

The problem here is nothing to do with the DOM node you are trying to construct, but rather with the input node.

Saxon's native tree models represent names of elements and attributes using an integer code which is mapped to the actual name using a look-up table held in the NamePool, which is owned by the Configuration. Stylesheets and queries are compiled to a form which searches for the namecode as an integer, rather than searching for the name as a string. This means that all the documents involved in a transformation must use the same NamePool, which for practical purposes usually means they must use the same Configuration.

I guess from the context that inputNode is an XdmNode. You haven't told us how it was created, but ultimately it must derive from an instance of net.sf.saxon.s9api.Processor, which is a wrapper class around a Configuration.

The TransformerFactory has been created independently of the s9api Processor, which means it will contain a different Configuration.

It's probably best not to mix s9api and JAXP interfaces in this way, but if you do, you must ensure that everyone is singing off the same NamePool, which you can do by explicitly assigning the same Configuration to either the Processor or the TransformerFactory or both. For example you could do

((TransformerFactoryImpl)tFactory).setConfiguration(processor.getUnderlyingConfiguration());

The term identity transformation in the post you cite refers to a JAXP concept where you can run a transformation without any stylesheet, by calling transformerFactory.newTransformer() with no arguments to get a transformer that is equivalent to the one you would get with an XSLT stylesheet that simply does @<xsl:copy-of select="/"/>@

RE: XdmNode to org.w3c.dom.Node - Added by Dimitrios Iakovidis over 6 years ago

Thank you for your answer and your time explaining things. I will give it a try. Meanwhile i tried an other approach:

Processor processor = xdmNode.getProcessor();
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
javax.xml.parsers.DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc= dBuilder.newDocument();
DOMDestination dest= new DOMDestination(doc);
processor.writeXdmValue(xdmNode, dest);

and it seems to work for now

    (1-2/2)

    Please register to reply