Home > Mobile >  Losing data field when converting XML string to JSON with xml-js or xml2js
Losing data field when converting XML string to JSON with xml-js or xml2js

Time:08-11

I am trying to convert an xml string to json. All the data until now has been loading successfully, but then I discovered that sometimes when reading the data, the point did not exist.

Using this xmlString:

<!DOCTYPE Metadata SYSTEM "/data/someConfig/path"><Metadata>
    <Standard>
        <Priority>Medium</Priority>
        <DueDate/>
        <Comment/>
        <Size/>
    </Standard>
    <PublicationsInformation/>
    <Details>
        <CommissionedCount/>
    </Details>
    <EventDetails>
        <EventContacts>
            <EventContact>
                <PersonName/>
                <PersonEmail/>
                <PersonPhone/>
            </EventContact>
        </EventContacts>
        <Journalist>
            <PersonName>Journalist name here</PersonName>
        </Journalist>
    </EventDetails>
    <Location>
        <SubLocation>Sydney NSW, Australia</SubLocation>
        <Suburb>Sydney</Suburb>
        <State>NSW</State>
        <Country>AU</Country>
        <Latitude/>
        <Longitude/>
        <AdditionalLocationDetails/>
        <Lat>-33.8688197</Lat>
        <Lng>151.2092955</Lng>
    </Location>
    <EventAssignedTo>
        <InternalUserEmails/>
        <InternalUserSMS/>
        <InternalUserNames/>
    </EventAssignedTo>
    <TestPath>
        <EventName>An event name</EventName>
    </TestPath>
</Metadata>

Run in this code:

export const getCurrentMetaData = (ctx: any): object => {
    const xmlStr = serializer.serializeToString(xmlMetaData);


    console.log('XML string: ') 
    console.log(xmlStr)


    const options = { compact: true, spaces: 4 };
    const json = xml2js(xmlStr, options);

    
    console.log('Converted to json: ')
    console.log(json)
    
    return json;
};

I get this output object:

{
{
    "_doctype": "Metadata SYSTEM \"/data/someConfig/path"",
    "Metadata": {
        "Standard": {
            "Priority": {
                "_text": "Medium"
            },
            "DueDate": {},
            "Comment": {},
            "Size": {}
        },
        "PublicationsInformation": {},
        "Details": {
            "CommissionedCount": {}
        },
        "EventDetails": {
            "EventContacts": {
                "EventContact": [
                    {
                        "PersonName": "",
                        "PersonEmail": "",
                        "PersonPhone": ""
                    }
                ]
            }
        },
        "Location": {
            "SubLocation": {
                "_text": "Sydney NSW, Australia"
            },
            "Suburb": {
                "_text": "Sydney"
            },
            "State": {
                "_text": "NSW"
            },
            "Country": {
                "_text": "AU"
            },
            "Latitude": {},
            "Longitude": {},
            "AdditionalLocationDetails": {},
            "Lat": {
                "_text": "-33.8688197"
            },
            "Lng": {
                "_text": "151.2092955"
            }
        },
        "EventAssignedTo": {
            "InternalUserEmails": {},
            "InternalUserSMS": {},
            "InternalUserNames": {}
        },
        "TestPath": {
            "EventName": {
                "_text": "An event name"
            }
        }
    }
}

As you can see, the Journalist.PersonName is missing here. Furthermore, if I use lodash.get(obj, 'Metadata.EventDetails.Journalist.PersonName._text') I get the information, even if I don't see the data on the actual object when printing it. What is happening here, and do anyone have any idea how to fix it?

CodePudding user response:

I've tested this with fast-xml-parser which returns the output you need.

const json = '{"Metadata":{"Standard":{"Priority":"Medium","DueDate":"","Comment":"","Size":""},"PublicationsInformation":"","Details":{"CommissionedCount":""},"EventDetails":{"EventContacts":{"EventContact":{"PersonName":"","PersonEmail":"","PersonPhone":""}},"Journalist":{"PersonName":"Journalist name here"}},"Location":{"SubLocation":"Sydney NSW, Australia","Suburb":"Sydney","State":"NSW","Country":"AU","Latitude":"","Longitude":"","AdditionalLocationDetails":"","Lat":-33.8688197,"Lng":151.2092955},"EventAssignedTo":{"<InternalUserEmails":"","InternalUserSMS":"","InternalUserNames":""},"TestPath":{"EventName":"An event name"}}}';

const data = JSON.parse(json);
console.log(data.Metadata.EventDetails.Journalist.PersonName);

CodePudding user response:

i tested with camaro and it works fine too.

var { transform } = require("camaro")

const xml = `<!DOCTYPE Metadata SYSTEM "/data/someConfig/path"><Metadata>
    <Standard>
        <Priority>Medium</Priority>
        <DueDate/>
        <Comment/>
        <Size/>
    </Standard>
    <PublicationsInformation/>
    <Details>
        <CommissionedCount/>
    </Details>
    <EventDetails>
        <EventContacts>
            <EventContact>
                <PersonName/>
                <PersonEmail/>
                <PersonPhone/>
            </EventContact>
        </EventContacts>
        <Journalist>
            <PersonName>Journalist name here</PersonName>
        </Journalist>
    </EventDetails>
    <Location>
        <SubLocation>Sydney NSW, Australia</SubLocation>
        <Suburb>Sydney</Suburb>
        <State>NSW</State>
        <Country>AU</Country>
        <Latitude/>
        <Longitude/>
        <AdditionalLocationDetails/>
        <Lat>-33.8688197</Lat>
        <Lng>151.2092955</Lng>
    </Location>
    <EventAssignedTo>
        <InternalUserEmails/>
        <InternalUserSMS/>
        <InternalUserNames/>
    </EventAssignedTo>
    <TestPath>
        <EventName>An event name</EventName>
    </TestPath>
</Metadata>
`

const template = {
    personName: '/Metadata/EventDetails/Journalist/PersonName',
    testPathEventName: '/Metadata/TestPath/EventName'
}

console.log(await transform(xml, template))

output

Object {personName: "Journalist name here", testPathEventName: "An event name"}
  • Related