eXist-db 4.4.0
When you run the following code you get illegal XML
xquery version "3.0";
let $xml :=
<MCCI_IN200101 xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7nl="urn:hl7-nl:v3">
โโโโโโโโ<effectiveTime xsi:type="hl7nl:PIVL_TS"/>
โโโโ</MCCI_IN200101>
return
for $in in $xml/*
return
element {name($in)} {
$in/@*,
for $nsp in in-scope-prefixes($in)
return
namespace {$nsp} {namespace-uri-for-prefix($nsp, $in)}
,
$in/node()
}
Actual output:
<effectiveTime xmlns="urn:hl7-org:v3" xmlns:hl7nl="urn:hl7-nl:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="" xsi:type="hl7nl:PIVL_TS"/>
Expected output:
<effectiveTime xmlns="urn:hl7-org:v3" xmlns:hl7nl="urn:hl7-nl:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="hl7nl:PIVL_TS"/>
I think this may be a variant or duplicate of https://github.com/eXist-db/exist/issues/1237.
@joewiz i agree, exist should not output illegal xml here.
actually when executing the code from the OP, Saxon returns an error for me:
9.8.0.12 EE (via oXygen)
Cannot output a namespace node for the default namespace when the element is in no namespace
--
If I modify the code to take the empty namespace of the root element of the return statement element {name($in)} into account, i get the desired result:
xquery version "3.0";
let $xml :=
<MCCI_IN200101 xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7nl="urn:hl7-nl:v3">
โโโโโโโโ<effectiveTime xsi:type="hl7nl:PIVL_TS"/>
โโโโ</MCCI_IN200101>
return
for $in in $xml/*
return
element {fn:QName('urn:hl7-org:v3', name($in))} {
$in/@*,
for $nsp in in-scope-prefixes($in)
return
namespace {$nsp} {namespace-uri-for-prefix($nsp, $in)}
,
$in/node()
}
Saxon returns the expected result
<effectiveTime xmlns:hl7nl="urn:hl7-nl:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:hl7-org:v3"
xsi:type="hl7nl:PIVL_TS"/>
exist however
err:XQDY0074 prefix cannot be cast to xs:NCName
So namespace are fun, right?
a somewhat simplified version of the OPs query
xquery version "3.0";
let $xml :=
<no_pre xmlns="foo" xmlns:xsi="http://XMLSchema-instance" xmlns:pre1="bar">
โโโโโโโโ<effectiveTime xsi:type="pre1:foobar"/>
โโโโ</no_pre>
return
for $in in $xml/*
return
element {fn:QName('foo', name($in))} {
$in/@*,
for $nsp in in-scope-prefixes($in)
return
namespace {$nsp} {namespace-uri-for-prefix($nsp, $in)}
,
$in/node()
}
so looking at our own testsuite (!) it seems we are well aware of the NCName behaviour:
this seems to have somewhat dropped under the radar. While there are workarounds, any insights into how to fix this @eXist-db/core ?
see #2140
@duncdrum Yes, I think one of my changes for #2140 should fix that.
So Bug 1 has been fixed, that is a badly formatted query now results in the appropriate error instead of not well-formed xml. ๐
Bug2 however is still present, here is a proper test.
xquery version "3.1";
module namespace t="http://exist-db.org/xquery/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
(:~ @see https://github.com/eXist-db/exist/issues/2183
:)
declare variable $t:xml := document {
<MCCI_IN200101 xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7nl="urn:hl7-nl:v3">
<effectiveTime xsi:type="hl7nl:PIVL_TS"/>
</MCCI_IN200101>
};
(:~ function throws an err:XQDY0074 it should not switch below to verify :)
declare
%test:assertTrue
(: %test:expectError('err:XQDY0074'):)
function t:NCName_namespace() {
let $test := for $in in $t:xml/*
return
element {fn:QName('urn:hl7-org:v3', name($in))} {
$in/@*,
for $nsp in in-scope-prefixes($in)
return
namespace {$nsp} {namespace-uri-for-prefix($nsp, $in)}
,
$in/node()
}
let $proof := <effectiveTime xmlns:hl7nl="urn:hl7-nl:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:hl7-org:v3"
xsi:type="hl7nl:PIVL_TS"/>
return
deep-equal($proof, $test)
};
tested in 5.3.0-SNAPSHOT (Exist-build: 20200608161727)
hold on a second getting conflicting results from XQsuite and simply executing the query.
ok executing the following query in exide results in err:XQDY0074 prefix cannot be cast to xs:NCName
xquery version "3.1";
declare variable $xml :=
<MCCI_IN200101 xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7nl="urn:hl7-nl:v3">
<effectiveTime xsi:type="hl7nl:PIVL_TS"/>
</MCCI_IN200101>
;
declare function local:test() {
for $in in $xml/*
return
element {fn:QName('urn:hl7-org:v3', name($in))} {
$in/@*,
for $nsp in in-scope-prefixes($in)
return
namespace {$nsp} {namespace-uri-for-prefix($nsp, $in)}
,
$in/node()
}
};
local:test()
the same contents as XQsuite test, however, now seem to return the desired result ?!? aka the following passes.
xquery version "3.1";
module namespace t="http://exist-db.org/xquery/test";
declare namespace test="http://exist-db.org/xquery/xqsuite";
(:~ @see https://github.com/eXist-db/exist/issues/2183
:)
declare variable $t:xml :=
<MCCI_IN200101 xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7nl="urn:hl7-nl:v3">
<effectiveTime xsi:type="hl7nl:PIVL_TS"/>
</MCCI_IN200101>
;
(:~ function throws an err:XQDY0074 it should not switch below to verify :)
declare
%test:assertEquals('<effectiveTime xmlns:hl7nl="urn:hl7-nl:v3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="urn:hl7-org:v3"
xsi:type="hl7nl:PIVL_TS"/>')
(: %test:assertError('err:XQDY0074'):)
function t:NCName_namespace() {
for $in in $t:xml/*
return
element {fn:QName('urn:hl7-org:v3', name($in))} {
$in/@*,
for $nsp in in-scope-prefixes($in)
return
namespace {$nsp} {namespace-uri-for-prefix($nsp, $in)}
,
$in/node()
}
};
frankly i don't see how that could ever be the case, the contents are simply copy-pasted.