使用Node.js反序列化奇怪的查询字符串

时间:2015-07-06 22:43:44

标签: node.js paypal deserialization query-string paypal-adaptive-payments

我有以下字符串,并希望将其反序列化为一个对象:

responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00
&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8
&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM
&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application

(顺便说一句 - 这是使用Classic API从PayPal Adaptive Payments获得的响应) https://developer.paypal.com/webapps/developer/docs/classic/api/adaptive-payments/Pay_API_Operation/

使用Node.js我可以使用

将其转换为项目数组
var qs = require('querystring');
var response = the-response-from-paypal;
var paypalResponse = qs.parse(response.toString());
console.log(paypalResponse["responseEnvelope.ack"])
//Renders:  Failure

但是我想把它转换成一个对象,可以像下面这样访问:

var ack = deserializedResponse.responseEnvelope.ack;
//etc

或者作为JSON:

{
    responseEnvelope: {
        ack: "Failure",
        timestamp: blah,
        correlationId: "a58a06c1000d8",
        ...
    },
    error: [
        {
            errorId: 520003,
            domain: "Platform",
            ...
        }
    ]

}

是否有一些方便的工具可以做到这一点?

1 个答案:

答案 0 :(得分:1)

根据我对你的其他SO question的回答。您只需要在预处理中包装递归函数,该预处理将为您构建整个对象。

var newObj = input.split('&').reduce(function (o, str) {
  var pair = str.split('=');

  return setObjVal(o, pair[0].split('.'), pair[1]);
}, {});

function setObjVal(obj, paths, val) {
  var path;
  var arrayInfo;

  if (paths.length === 0) {
    return val;
  }

  obj = obj || {};
  path = paths.shift();
  arrayInfo = path.match(arrayRegExp);

  if (arrayInfo) {
    path = arrayInfo[1];

    if (!Array.isArray(obj[path])) {
      obj[path] = [];
    }

    obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
  }
  else {
    obj[path] = setObjVal(obj[path], paths, val);
  }

  return obj;
}



var arrayRegExp = /^(\w+)\((\d+)\)$/;

var input = 'responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application';

var newObj = input.split('&').reduce(function (o, str) {
  var pair = str.split('=');
  
  return setObjVal(o, pair[0].split('.'), pair[1]);
}, {});

function setObjVal(obj, paths, val) {
  var path;
  var arrayInfo;
  
  if (paths.length === 0) {
    return val;
  }

  obj = obj || {};
  path = paths.shift();
  arrayInfo = path.match(arrayRegExp);
  
  if (arrayInfo) {
    path = arrayInfo[1];
    
    if (!Array.isArray(obj[path])) {
      obj[path] = [];
    }
    
    obj[path][arrayInfo[2]] = setObjVal(obj[path][arrayInfo[2]], paths, val);
  }
  else {
    obj[path] = setObjVal(obj[path], paths, val);
  }
  
  return obj;
}

document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
&#13;
&#13;
&#13;

或者如果您想在其他答案中使用lodash,可以使用_.set()

var newObj = input.split('&').reduce(function (o, str) {
  var pair = str.split('=');

  return _.set(o, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
}, {});

&#13;
&#13;
var input = 'responseEnvelope.timestamp=2015-07-06T15%3A20%3A49.534-07%3A00&responseEnvelope.ack=Failure&responseEnvelope.correlationId=a58a06c1000d8&responseEnvelope.build=15743565&error(0).errorId=520003&error(0).domain=PLATFORM&error(0).subdomain=Application&error(0).severity=Error&error(0).category=Application';

var newObj = input.split('&').reduce(function (o, str) {
  var pair = str.split('=');

  return _.set(o, pair[0].replace(/\(/g, '[').replace(/\)/g, ']'), pair[1]);
}, {});

document.write('<pre>' + JSON.stringify(newObj, null, 4) + '</pre>');
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js"></script>
&#13;
&#13;
&#13;