exist icon indicating copy to clipboard operation
exist copied to clipboard

XQuery Update ignores namespace binding conflict

Open joewiz opened this issue 7 years ago • 8 comments

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

joewiz avatar Jul 17 '17 13:07 joewiz

still happening in 4.2.1 and 5.0.0 RC

duncdrum avatar Jun 14 '18 12:06 duncdrum

we should add these as pending tests

duncdrum avatar Jan 11 '19 10:01 duncdrum

Agreed.

joewiz avatar May 31 '19 16:05 joewiz

Test still fails in eXist 5.0.0.

joewiz avatar Sep 10 '19 13:09 joewiz

@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 avatar Mar 09 '20 17:03 adamretter

@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.

joewiz avatar Mar 09 '20 18:03 joewiz

Is this considered a breaking change? As the milestone is set to v7.

line-o avatar Jul 28 '22 12:07 line-o

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:

  1. 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.]

adamretter avatar Sep 06 '22 08:09 adamretter