JSON to JSON transformer

后端 未结 7 2058
醉话见心
醉话见心 2020-11-30 03:36

I got a scenario.

Required input and output are JSON.

// Input
{
  \"OldObject\": {
    \"Time\": 1351         


        
相关标签:
7条回答
  • 2020-11-30 03:44

    Try JOLT. It is a JSON to JSON transformation library written in Java. It was created on a project that was transforming lot of JSON from an ElasticSearch "backend" to a frontend api.

    For the JSON transform you have listed in your problem, the Jolt "shift" spec would be :

    // Jolt "shift" spec
    {
        "OldObject": {
            "Time": "NewObject.Time",   
            "Name": "NewObject.Title", // if the input has "OldObject.Name", copy it's value
                                       // to "NewObject.Title
            "quantity": "NewObject.quantity"
        }
    }
    
    0 讨论(0)
  • 2020-11-30 03:47

    You can do this transformation with JSON patch.

    Example with jsonpatch-js:

    var transformations = [
      { move: '/OldObject', to: '/NewObject' },
      { remove: '/NewObject/price' },
      { move: '/NewObject/Name', to: '/NewObject/Title' }
    ];
    
    var oldObject = { "OldObject": { "Time": 1351160457922, "Name": "OName", "quantity": 100, "price": 10 } };
    
    jsonpatch.apply(oldObject, transformations);
    

    I did not test the provided, but should work like that.

    There are Java implementations for JSON patch:

    0 讨论(0)
  • 2020-11-30 03:47

    Javascript JSON Transformer : https://raw.githubusercontent.com/udhayasoftware/codebase/master/standalone/javascript/TransformJSON.js

    We can convert JSON array to JSON object and vice versa. The only thing is we need to be careful in defining the xPaths.

    //Transforming JSON array to JSON object:
     var inputObj = [{Name:"Senyora"},{Name:"Clinton"}]
     sourceXpath = "[].Name";
     targetXpath = "Marriage.Couples[].NewName";
     // Output = {Marriage:{Couples:[{NewName:"Senyora"},{NewName:"Clinton"}]}}
    
    
     //Transforming JSON object to JSON array:
     var inputObj = {Marriage:{Couples:[{NewName:"Senyora"},{NewName:"Clinton"}]}}
     sourceXpath = "Marriage.Couples[].NewName";
     targetXpath = "[].Name";
     // Output = [{Name:"Senyora"},{Name:"Clinton"}]
    

    /*
    
     Author: Udhayamoorthy
     Email: udhayaraagam@gmail.com"
    
     */
    
    //Code start
    
    function prepareGroup(inputObj, flatted, sourceXpath) {
        sourceXpath = sourceXpath.replace(/\[]/g, ".[0-9]*");
        var reg = new RegExp(sourceXpath, "g")
        var strVal = JSON.stringify(flatted).match(reg);
        var groupVal = {};
        if (strVal != null)
            strVal.forEach(function (data) {
                if (flatted[data] != undefined) {
                    groupVal[data] = flatted[data];
                } else {
                    data = data.replace(/"/g, "");
                    groupVal[data] = getValue(inputObj, data);
                }
            })
        return groupVal;
    }
    
    function processGrouped(obj, targetXpath) {
        var flatOutput = {};
        var keys = Object.keys(obj);
        targetXpath = targetXpath.replace(/\[]./g, "[0-9]");
        for (var i = 0; i < keys.length; i++) {
            var key = keys[i];
            var changed = key.match(/(^[0-9]*\.|\W[0-9]*\.)/g);
            if (changed) {
                changed = JSON.stringify(changed).replace(/\"\./g, "\"");
            }
            var arrapos = '';
            try {
                arrapos = JSON.parse(changed);
            }
            catch (e) {
                arrapos = changed;
            }
            var temp = targetXpath;
            if (arrapos != null) {
                arrapos.forEach(function (pos) {
                    pos = "." + pos;
                    temp = temp.replace("[0-9]", pos)
                })
            }
            //tinkering - started
            if (temp.charAt(0) == ".") {
                temp = temp.substring(1, temp.length);
            }
            //tinkering - end
            flatOutput[temp] = obj[key];
        }
        return unflatten(flatOutput);
    }
    
    function merge(a, b) {
        for (var key in b)
            if (b.hasOwnProperty(key)) {
                var src = a[key];
                var dest = b[key];
                if (typeof src === 'object' && typeof dest === 'object') {
                    merge(src, dest);
                } else {
                    a[key] = b[key];
                }
            }
        return a;
    };
    
    function getValue(localObj, xpath) {
        //var localObj = JSON.parse(JSON.stringify(obj));
        var xpathArr = xpath.split('.');
        xpathArr.forEach(function (path) {
            localObj = localObj[path];
        })
        return localObj;
    }
    
    function unflatten(target, opts) {
        var opts = opts || {}
            , delimiter = opts.delimiter || '.'
            , result = {}
    
        if (Object.prototype.toString.call(target) !== '[object Object]') {
            return target
        }
    
        function getkey(key) {
            var parsedKey = parseInt(key)
            return (isNaN(parsedKey) ? key : parsedKey)
        };
    
        Object.keys(target).forEach(function (key) {
            var split = key.split(delimiter)
                , firstNibble
                , secondNibble
                , recipient = result
    
            firstNibble = getkey(split.shift())
            secondNibble = getkey(split[0])
    
            while (secondNibble !== undefined) {
                if (recipient[firstNibble] === undefined) {
                    recipient[firstNibble] = ((typeof secondNibble === 'number') ? [] : {})
                }
    
                recipient = recipient[firstNibble]
                if (split.length > 0) {
                    firstNibble = getkey(split.shift())
                    secondNibble = getkey(split[0])
                }
            }
    
            // unflatten again for 'messy objects'
            recipient[firstNibble] = unflatten(target[key])
        });
    
        //Array Check
        var keys = Object.keys(result);
        if (keys.length > 0 && keys[0] === "0") {
            var output = [];
            keys.forEach(function (key) {
                output.push(result[key])
            });
            return output;
        }
        return result
    };
    
    function flatten(target, opts) {
        var output = {}
            , opts = opts || {}
            , delimiter = opts.delimiter || '.'
    
        function getkey(key, prev) {
            return prev ? prev + delimiter + key : key
        };
    
        function step(object, prev) {
            Object.keys(object).forEach(function (key) {
                var isarray = opts.safe && Array.isArray(object[key])
                    , type = Object.prototype.toString.call(object[key])
                    , isobject = (type === "[object Object]" || type === "[object Array]")
    
                if (!isarray && isobject) {
                    return step(object[key]
                        , getkey(key, prev)
                    )
                }
    
                output[getkey(key, prev)] = object[key]
            });
            if (Object.keys(object) == "") {
                if (object instanceof Array) {
                    output[prev] = [];
                } else {
                    output[prev] = {};
                }
            }
        };
        step(target)
        return output
    };
    
    function isChildAttribute(map, flatted, mapArray) {
        var parent = map.sourceXpath;
        for (var j = 0; j < mapArray.length; j++) {
            var child = mapArray[j].sourceXpath;
            if (child.indexOf(parent) != -1 && parent.length < child.length) {
                if (child.indexOf(parent + ".") != -1 || child.indexOf(parent + "[]") != -1) {
                    var temp = child;
                    temp = temp.replace(/\[]/g, ".0");
                    if (flatted[temp] != undefined) {
                        return false;
                    }
                }
            }
        }
        return true;
    }
    
    function transformJSON(inputObj, mapArray) {
        var flatted = flatten(inputObj);
        var finalout = {};
        if (mapArray.length > 0 && (mapArray[0].targetXpath).charAt(0) == "[")
            finalout = [];
        mapArray.forEach(function (map) {
            if (isChildAttribute(map, flatted, mapArray)) {
                var grouped = prepareGroup(inputObj, flatted, map.sourceXpath);
                var output = processGrouped(grouped, map.targetXpath);
                finalout = merge(finalout, output);  // merge two json objects
            }
        });
        return finalout;
    }
    
    //Code end
    
    //How to use (See below) ??
    
    var inputObj = {
        a: {
            b: [
                {
                    Name: "Tommy",
                    Location: [
                        {Place: "Sydney"},
                        {Place: "Washington"}
                    ],
                    Info: {age: 23}
                },
                {
                    Name: "Sara",
                    Location: [
                        {Place: "New York"},
                        {Place: "New Jercy"}
                    ],
                    Info: {age: 34}
                },
                {
                    Name: "John",
                    Location: [
                        {Place: "Chicago"},
                        {Place: "Detroit"}
                    ],
                    Info: {age: 78}
                }
            ],
            d: {
                e: {
                    f: {
                        g: {
                            h: "I Love India"
                        }
                    }
                }
            }
        }
    };
    
    var mapArray = [];     // collect source and target xpath s
    var obj = {};
    obj.sourceXpath = "a.b[].Name"; // Name is string
    obj.targetXpath = "x[].NewName"; // expecting NewName as string
    mapArray.push(obj);
    
    //obj = {};
    //obj.sourceXpath = "a.b[].Location"; // Location is an array
    //obj.targetXpath = "x[].NewName"; // INVALID MAPPING - NewName already mapped
    //mapArray.push(obj);
    
    obj = {};
    obj.sourceXpath = "a.b[].Location"; // Location is an array
    obj.targetXpath = "x[].NewLocation"; // Location data copied to NewLocation array(Place will be present in array elements)
    mapArray.push(obj);
    
    obj = {};
    obj.sourceXpath = "a.b[].Location[].Place"; // Location is an array
    obj.targetXpath = "x[].NewLocation[].NewPlace"; // NewPlace will be created parallel to existing Place.
    mapArray.push(obj);
    
    obj = {};
    obj.sourceXpath = "a.d.e.f.g.h"; // Transforming attributes at different level
    obj.targetXpath = "T.H";
    mapArray.push(obj);
    
    var finalout = transformJSON(inputObj, mapArray);
    console.log("See line#204 for more about how to use?");
    console.log("Transformed JSON = " + JSON.stringify(finalout));

    Caution: JSON can't be transformed between different dimensions of array. Count of '[]' in sourceXpath should be equals to count of '[]' in targetXpath and vice versa.

    0 讨论(0)
  • 2020-11-30 03:51

    You can try Java library Silencio that allows you to convert each node of the JSON file into new values. You can decide which and how nodes should be transformed.

    0 讨论(0)
  • 2020-11-30 03:53

    You can try jmom a little java library

    String jsonstring = "...";
    JsonValue json = JsonParser.parse(jsonstring);
    Jmom jmom = Jmom.instance()
                .copy("/OldObject", "/NewObject", true)
                .remove("/NewObject/price")
                .copy("/NewObject/Name", "/NewObject/Title", true);
    jmom.apply(json);
    jsonstring = json.toCompactString();
    
    0 讨论(0)
  • 2020-11-30 03:55

    You can use ZORBA and JsonIQ http://www.jsoniq.org/ However, it's a native library, it comes with a wrapper so you can use it in java.

    0 讨论(0)
提交回复
热议问题