s-yadav / jsonQ

A JavaScript library to make manipulation and extraction of data from a JSON very easy and fast.
MIT License
202 stars 69 forks source link

find traversal method not returning as expected. Bug? #15

Open Tzaphkiel opened 7 years ago

Tzaphkiel commented 7 years ago

Provided we parse the following XML:

<?xml version='1.0' encoding='UTF-8'?>
<mes:Structure xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:mes="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message" xmlns:str="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/structure" xmlns:com="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/common" xsi:schemaLocation="http://www.sdmx.org/resources/sdmxml/schemas/v2_1/message https://registry.sdmx.org/schemas/v2_1/SDMXMessage.xsd">
    <mes:Header>
        <mes:ID>IDREF93428</mes:ID>
        <mes:Test>false</mes:Test>
        <mes:Prepared>2017-02-16T09:34:05</mes:Prepared>
        <mes:Sender id="ECB" />
        <mes:Receiver id="not_supplied" />
    </mes:Header>
    <mes:Structures>
        <str:OrganisationSchemes>
            <str:AgencyScheme urn="urn:sdmx:org.sdmx.infomodel.base.AgencyScheme=ECB:AGENCIES(1.0)" isExternalReference="false" agencyID="ECB" id="AGENCIES" isFinal="false" version="1.0">
                <com:Name xml:lang="en">Agencies</com:Name>
                <str:Agency urn="urn:sdmx:org.sdmx.infomodel.base.Agency=ECB.DISS" id="DISS">
                    <com:Name xml:lang="en">ECB Dissemination</com:Name>
                </str:Agency>
            </str:AgencyScheme>
            <str:AgencyScheme urn="urn:sdmx:org.sdmx.infomodel.base.AgencyScheme=SDMX:AGENCIES(1.0)" isExternalReference="false" agencyID="SDMX" id="AGENCIES" isFinal="false" version="1.0">
                <com:Name xml:lang="en">SDMX Agency Scheme</com:Name>
                <str:Agency urn="urn:sdmx:org.sdmx.infomodel.base.Agency=SDMX" id="SDMX">
                    <com:Name xml:lang="en">SDMX</com:Name>
                </str:Agency>
                <str:Agency urn="urn:sdmx:org.sdmx.infomodel.base.Agency=ECB" id="ECB">
                    <com:Name xml:lang="en">European Central Bank</com:Name>
                </str:Agency>
                <str:Agency urn="urn:sdmx:org.sdmx.infomodel.base.Agency=EUROSTAT" id="EUROSTAT">
                    <com:Name xml:lang="en">Eurostat</com:Name>
                </str:Agency>
                <str:Agency urn="urn:sdmx:org.sdmx.infomodel.base.Agency=IMF" id="IMF">
                    <com:Name xml:lang="en">International Monetary Fund</com:Name>
                </str:Agency>
                <str:Agency urn="urn:sdmx:org.sdmx.infomodel.base.Agency=ESTAT" id="ESTAT">
                    <com:Name xml:lang="en">Eurostat</com:Name>
                </str:Agency>
            </str:AgencyScheme>
        </str:OrganisationSchemes>
    </mes:Structures>
</mes:Structure>

into a JSON object like this and then use find:

import convert from 'xml-to-json-promise'
import jsonQ from "jsonq"
//data contains the XML
convert.xmlDataToJSON(
  data, 
  {explicitRoot: false, xmlns: false, explicitArray: false}
).then(json => {
  var jqo = jsonQ(json)
  console.log(jqo.find('str:Agency').value())
})

we get the following JSON output:

[ { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=ECB.DISS',
       id: 'DISS' },
    'com:Name': { _: 'ECB Dissemination', '$': [Object] } },
  [ { '$': [Object], 'com:Name': [Object] },
    { '$': [Object], 'com:Name': [Object] },
    { '$': [Object], 'com:Name': [Object] },
    { '$': [Object], 'com:Name': [Object] },
    { '$': [Object], 'com:Name': [Object] } ] ]

where elem 1 is an Agency object but elem 2 is an array of Agency objects... I was expecting the following JSON:

[
 { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=ECB.DISS',
       id: 'DISS' },
    'com:Name': { _: 'ECB Dissemination', '$': [Object] } },
 { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=SDMX',
       id: 'SDMX' },
    'com:Name': { _: '...', '$': [Object] } },
 { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=ECB',
       id: 'ECB' },
    'com:Name': { _: '...', '$': [Object] } },
 { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=EUROSTAT',
       id: 'EUROSTAT' },
    'com:Name': { _: '...', '$': [Object] } },
 { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=IMF',
       id: 'IMF' },
    'com:Name': { _: '...', '$': [Object] } },
 { '$':
     { urn: 'urn:sdmx:org.sdmx.infomodel.base.Agency=ESTAT',
       id: 'ESTAT' },
    'com:Name': { _: '...', '$': [Object] } }
]

all in one array. Even if their parents are different, we are looking for all Agency irrespective of the parentage and should hence get an array of Agency and not a mixed array.

What do you think ?