eXist-db / exist

eXist Native XML Database and Application Platform
https://exist-db.org
GNU Lesser General Public License v2.1
429 stars 180 forks source link

Fragment selection skips namespace declaration for xsi:type value #2182

Open ahenket opened 6 years ago

ahenket commented 6 years ago

When you select a piece of XML , all relevant namespace declarations are copied into the fragment, except when the @xsi:type value has one. The net result is now an invalid fragment.

Tested with eXist-db 2.2 and 4.4.0 on macOS Mojave, you may run the following code to reproduce:

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
    $xml/*

Actual result:

<effectiveTime xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="hl7nl:PIVL_TS"/>

Expected result: <effectiveTime xmlns="urn:hl7-org:v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:hl7nl="urn:hl7-nl:v3" xsi:type="hl7nl:PIVL_TS"/>

joewiz commented 6 years ago

I'm genuinely unsure where in the spec the feature that would yield the expected outcome is stated or implied. Is it the static typing feature, https://www.w3.org/TR/xquery-31/#id-static-typing-feature?

For comparison:

duncdrum commented 6 years ago

I m very much leaning to Saxon being right, and both eXist and BaseX being wrong. @adamretter thoughts?

ahenket commented 6 years ago

xsi:type is a QName() https://www.w3.org/TR/xmlschema11-1/#xsi_type

A QName() may have a prefix and a prefix needs declaration. I'd say Saxon is right. Without the declaration I cannot pass schema validation, so that's another indication.

joewiz commented 6 years ago

@ahenket Thank you for that reference. I actually meant "where in the XQuery spec". I'd like to be able to point to a section in the XQuery specification that says that processors must respect this. There are a number of schema- and type- related features that are labeled "optional" here: https://www.w3.org/TR/xquery-31/#id-conform-optional-features. And eXist's documentation says which optional features it doesn't support: http://exist-db.org/exist/apps/doc/xquery.xml#unsupported-features.

Basically, I'm wondering whether this is a bug (failure to implement a required feature) or just an omission of an optional feature.

To know how to classify this, we'll need to find the place in the XQuery specification that addresses this.

ahenket commented 6 years ago

I can only say that if you don't respect the QName(), you may end up with illegal XML. I don't see how you could skip implementation in that sense. And so I cannot see how it could be optional.

duncdrum commented 6 years ago

no bad query here, just a bug

joewiz commented 6 years ago

Duncan, do you see where in the spec the required behavior is described?

ahenket commented 6 years ago

In the mean time I have worked my way around it. This had to be done in two steps:

That is enough for schema validation, but not for schematron validation as upon transform:transform() eXist kicks in and kills my carefully crafted namespace declarations again thus leading to incorrect errors, so step 2:

These are really nasty hacks that I'd appreciate getting rid of.

add-namespace.xsl.txt

duncdrum commented 6 years ago

@joewiz i d say thats here https://www.w3.org/TR/xquery-31/#id-ns-nodes-on-elements but I can't really see how the differences between basex/exist and saxon are covered there.

One could argue that the following:

Copy-namespaces mode does not affect the namespace bindings of a newly constructed element node. It applies only to existing nodes that are copied by a constructor expression.

implies xmlns:hl7nl="urn:hl7-nl:v3" can be dropped since it is not in use for the newly constructed element $xml/*, but the prefix should still be resolved imv (ala Saxon), hence i m leaning to bug.