exist
exist copied to clipboard
XQuery Update ignores namespace binding conflict
What is the problem
eXist's XQuery Update facility overlooks namespace binding conflicts when inserting attributes. For example, given a query whose prolog binds the namespace prefix myns
to the URI http://www.foo.com
, an update expression in that query to insert an attribute myns:baz="qux"
into a document where myns
is bound to a different namespace URI, like http://www.bar.com
, succeeds, despite the conflicting namespace bindings on the prefix myns
.
What did you expect
I expected an error to be raised — along the lines of what Saxon raises:
XUDY0023: An update action creates a namespace binding that conflicts with an existing namespace binding on the same target element
For more on this error, see https://www.w3.org/TR/xquery-update-30/#ERRXUDY0023. (While eXist's XQuery Update spec isn't aligned with the W3C spec, it seems reasonable that a namespace binding conflict should raise an error.)
Describe how to reproduce or add a test
xquery version "3.1";
module namespace ut="http://exist-db.org/xquery/update/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare namespace myns="http://www.foo.com";
declare variable $ut:test {
<x xmlns:myns="http://www.bar.com">
<z/>
</x>
};
declare %test:setup function ut:setup() {
xmldb:store("/db", "test.xml", $ut:test)
};
declare %test:teardown function ut:teardown() {
xmldb:remove("/db/test.xml")
};
declare %test:assertError("XUDY0023") function ut:insert-namespaced-attribute() {
update insert attribute myns:baz { "qux" } into doc("/db/test.xml")/x/z
};
The equivalent test in Saxon:
test.xml
<x xmlns:myns="http://www.bar.com">
<z/>
</x>
test.xq
xquery version "3.1";
declare namespace myns="http://www.foo.com";
let $doc := doc("test.xml")
return
insert node attribute myns:baz { "qux" } into $doc/x/z
Running this test in oXygen 19.0 (build 2017062918), the result is:
System ID: /Users/joe/Downloads/update-test/test.xq
Severity: error
Description: XUDY0023: An update action creates a namespace binding that conflicts with an existing namespace binding on the same target element
Start location: 7:39
Context information
- eXist-db version + Git Revision hash: 3.4.0-SNAPSHOT+201707142259 (af161fd52)
- Java version: 1.8.0_131
- Operating system: macOS 10.12.5
- 32 or 64 bit: 64 bit
- Any custom changes in e.g. conf.xml: No
still happening in 4.2.1 and 5.0.0 RC
we should add these as pending tests
Agreed.
Test still fails in eXist 5.0.0.
@joewiz Hmmm... would I not expect to get the result:
<x xmlns:myns="http://www.bar.com">
<z xmlns:myns="http://www.foo.com" myns:baz="qux"/>
</x>
@adamretter Yes, that would certainly be a valid result. However, eXist 5.2.0 returns the following result:
<x xmlns:myns="http://www.bar.com">
<z myns:baz="qux"/>
</x>
This is an incorrect result, since the @baz
attribute is bound to the bar.com
namespace URI instead of the foo.com
namespace URI it was bound to in the update expression.
Is this considered a breaking change? As the milestone is set to v7.
See the semantics numbered list under the examples in the spec here - https://www.w3.org/TR/xquery-update-10/#id-insert
Especially item 3, which talks about an $alist
:
- If $alist is not empty and any form of into is specified, the following checks are performed:
a. $target must be an element node [err:XUTY0022].
b. No attribute node in $alist may have a QName whose [implied namespace binding](https://www.w3.org/TR/xquery update-10/#dt-implied-namespace-binding) conflicts with a namespace binding in the "namespaces" property of $target [[err:XUDY0023](https://www.w3.org/TR/xquery-update 10/#ERRXUDY0023)], unless the namespace prefix for the attribute is absent.
c. Multiple attribute nodes in $alist must not have QNames whose implied namespace bindings conflict with each other [err:XUDY0024].
The definition of implied namespace bindings
is here - https://www.w3.org/TR/xquery-update-10/#dt-implied-namespace-binding
[Definition: The implied namespace binding of a QName is the association of its namespace prefix (or absence thereof) with its namespace URI (or absence thereof).] [Definition: Two namespace bindings are said to conflict if their namespace prefixes (or absence thereof) are the same but their namespace URI's (or absence thereof) are different.]