eXist-db / exist

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

[BUG] fn:xml-to-json may fail on stored XML representations of JSON #3989

Open amclark42 opened 3 years ago

amclark42 commented 3 years ago

Describe the bug fn:xml-to-json#1 will sometimes fail to translate a valid XML representation of JSON, when that XML has been stored in the database. The error returned is FOJS0006, “Invalid XML representation of JSON.”

Expected behavior I expected that the function would take the pseudo-JSON document or outermost node and convert the XML into a JSON string. The same XML can be successfully converted when it’s hard-coded in an XQuery variable.

To Reproduce

xquery version "3.1";

module namespace t="http://exist-db.org/xquery/test";
import module namespace jx="http://joewiz.org/ns/xquery/json-xml"
at "https://gist.githubusercontent.com/joewiz/d986da715facaad633db/raw/07f5eb5804673a38491bd4f4e6e26ca2986934cb/json-xml.xqm";
declare namespace err = "http://www.w3.org/2005/xqt-errors";
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare namespace test="http://exist-db.org/xquery/xqsuite";

    declare variable $t:XML := document {
        <map xmlns="http://www.w3.org/2005/xpath-functions">
            <string key="hello">World</string>
        </map>
    };

    declare
        %test:setUp
    function t:setup() {
        xmldb:store("/db", "test.xml", $t:XML)
    };

    declare
        %test:tearDown
    function t:tearDown() {
        xmldb:remove("/db", "test.xml")
    };

(:  TESTS  :)

    (:~ Turn stored pseudo-JSON XML into JSON. This one fails in v5.3.0. :)
    declare %test:assertTrue function t:exist-doc() {
        fn:xml-to-json(doc("/db/test.xml"))
    };

    (:~ Turn in-memory pseudo-JSON into JSON. :)
    declare %test:assertTrue function t:exist-in-memory() {
        fn:xml-to-json($t:XML)
    };

    (: Use Joe Wicentowski's shim for xml-to-json() to turn stored pseudo-JSON 
        into JSON. :)
    declare %test:assertTrue function t:shim-doc() {
        jx:xml-to-json(doc("/db/test.xml"))
    };

Context (please always complete the following information):

joewiz commented 3 years ago

@amclark42 Thank you for reporting this and developing tests!

I can reproduce the bug by running the supplied xqsuite test on my local 5.3.0 instance. The test suite returns:

<testsuite package="http://exist-db.org/xquery/test" timestamp="2021-07-29T14:26:28.618-04:00"
    tests="3" failures="0" errors="1" pending="0" time="PT0.003S">
    <testcase name="exist-doc" class="t:exist-doc">
        <error type="err:FOJS0006" message="Invalid XML representation of JSON."/>
    </testcase>
    <testcase name="exist-in-memory" class="t:exist-in-memory"/>
    <testcase name="shim-doc" class="t:shim-doc"/>
</testsuite>

The tests in https://github.com/eXist-db/exist/blob/develop/exist-core/src/test/xquery/xquery3/xml-to-json.xql do not test the application of the fn:xml-to-json function to nodes stored in the database.

dizzzz commented 3 years ago

Nice and clean test!