namespace declaration is lost with -pull
Added by Anonymous over 18 years ago
Legacy ID: #3627608 Legacy Poster: marcvc (marcvc)
Michael, using Saxon 8.7, consider the following query declare namespace p1 = "http://ns1"; declare namespace p2 = "http://ns2"; declare variable $input := element p1:input { element p2:output {()} }; $input/p2:output With the default settings, the result contains the p1 namespace declaration attribute. However, using the -pull option, this namespace declaration attribute seems to be missing. I have not verified behaviour with previous versions of Saxon. Thanks, Marc
Replies (4)
Please register to reply
RE: namespace declaration is lost with -pull - Added by Anonymous over 18 years ago
Legacy ID: #3629029 Legacy Poster: Michael Kay (mhkay)
You're right, it seems that there's no logic to implement namespace inheritance: that is, when a child element is copied to add it to a new parent, it isn't inheriting the namespaces of its parent. This will require some fairly careful investigation because it's intricate code that hasn't been touched for a while - I think it's very unlikely that the problem is new.
RE: namespace declaration is lost with -pull - Added by Anonymous over 18 years ago
Legacy ID: #3629144 Legacy Poster: marcvc (marcvc)
fyi (I assume this one is related) let $e1 := fn:QName("uri1", "p:e1") let $e2 := fn:QName("uri1", "p:e2") let $a3 := fn:QName("uri3", "p:a") return element {$e1} {element {$e2}{attribute {$a3}{""}}} The prefix conflict is not detected and as such returns incorrectly the following result: <p:e1 xmlns:p="uri1"> <p:e2 xmlns:p="uri3" p:a=""/> </p:e1> Regards, Marc
RE: namespace declaration is lost with -pull - Added by Anonymous over 18 years ago
Legacy ID: #3653539 Legacy Poster: Michael Kay (mhkay)
The first problem is solved by adding a NamespaceReducer to the construct() method as described in https://sourceforge.net/forum/forum.php?thread_id=1461263&forum_id=94027 This doesn't solve the second problem, because on this path the lazily-evaluated tree is never actually constructed: it causes a set of events to be piped straight to the serializer. But in fact, the conflict wouldn't be detected even if the tree were constructed, as is illustrated by changing the query to (: test namespace conflict on a constructed document (especially in pull mode) :) let $c := let $e1 := fn:QName("uri1", "p:e1") let $e2 := fn:QName("uri1", "p:e2") let $a3 := fn:QName("uri3", "p:a") return element {$e1} {element {$e2}{attribute {$a3}{""}}} return $c//@* This is because namespace conflicts are detected by the ComplexContentOutputter, not by the NamespaceReducer. So it appears we need to add a CCO to the pipeline in the construct() method, so that it reads: void construct() throws XPathException { PipelineConfiguration pipe = savedXPathContext.getController().makePipelineConfiguration(); PullProvider puller = getPuller(); puller.setPipelineConfiguration(pipe); TinyBuilder builder = new TinyBuilder(); builder.setPipelineConfiguration(pipe); builder.setSystemId(pipe.getLocationProvider().getSystemId(instruction.getLocationId())); NamespaceReducer reducer = new NamespaceReducer(); reducer.setUnderlyingReceiver(builder); reducer.setPipelineConfiguration(pipe); ComplexContentOutputter outputter = new ComplexContentOutputter(); outputter.setReceiver(reducer); outputter.setPipelineConfiguration(pipe); outputter.open(); new PullPushCopier(puller, outputter).copy(); outputter.close(); node = builder.getCurrentRoot(); } This solves the modified version of the second problem. I'll come back with further news on the second problem as originally stated in due course...
RE: namespace declaration is lost with -pull - Added by Anonymous over 18 years ago
Legacy ID: #3653586 Legacy Poster: Michael Kay (mhkay)
For the second problem, provided the -wrap option is not used, the prefix conflict can be handled by adding a ComplexContentOutputter to the XQueryExpression.pull() method, which becomes public void pull(DynamicQueryContext dynamicEnv, Result destination, Properties outputProperties) throws XPathException { try { SequenceIterator iter = iterator(dynamicEnv); PullProvider pull = new PullFromIterator(iter); pull = new PullNamespaceReducer(pull); pull.setPipelineConfiguration(executable.getConfiguration().makePipelineConfiguration()); Receiver receiver = SerializerFactory.getReceiver(destination, pull.getPipelineConfiguration(), outputProperties); NamespaceReducer reducer = new NamespaceReducer(); PipelineConfiguration pipe = pull.getPipelineConfiguration(); reducer.setPipelineConfiguration(pipe); reducer.setUnderlyingReceiver(receiver); ComplexContentOutputter outputter = new ComplexContentOutputter(); outputter.setReceiver(reducer); outputter.setPipelineConfiguration(pipe); if ("yes".equals(outputProperties.getProperty(SaxonOutputKeys.WRAP))) { receiver = new SequenceWrapper(outputter); } else { receiver = new TreeReceiver(outputter); } new PullPushCopier(pull, receiver).copy(); } catch (UncheckedXPathException e) { throw e.getXPathException(); } } This isn't solving the problem when both -pull and -wrap are specified, however. For that case the same change needs to be made to QueryResult.wrap(), which then reads: public static DocumentInfo wrap(SequenceIterator iterator, Configuration config) throws XPathException { PipelineConfiguration pipe = config.makePipelineConfiguration(); TinyBuilder builder = new TinyBuilder(); builder.setPipelineConfiguration(pipe); NamespaceReducer reducer = new NamespaceReducer(); reducer.setUnderlyingReceiver(builder); reducer.setPipelineConfiguration(pipe); ComplexContentOutputter outputter = new ComplexContentOutputter(); outputter.setPipelineConfiguration(pipe); outputter.setReceiver(reducer); sendWrappedSequence(iterator, outputter); return (DocumentInfo)builder.getCurrentRoot(); } I'm not convinced this is an ideal solution, because the ComplexContentOutputter is a rather heavyweight class - it does a lot of checking of things that don't need to be checked in these situations, and does buffering of attribute values and text content. It will do for now; but for the final solution, I'm going to explore extracting the namespace conflict resolution code either into NamespaceReducer or into a new filter that can be added to the pipeline when needed.
Please register to reply