为什么findItemsAdvanced(eBay查找API)JSON结果元素都是所有数组?

时间:2014-11-16 21:42:58

标签: javascript xml json ebay ebay-api

使用RESPONSE-DATA-FORMAT=XML致电findItemsAdvanced时,结果符合预期,例如:

<findItemsAdvancedResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
  <ack>Success</ack>
  <version>1.13.0</version>
  <timestamp>2014-11-16T20:59:57.588Z</timestamp>
  <searchResult count="0"/>
  <paginationOutput>
    <pageNumber>0</pageNumber>
    <entriesPerPage>100</entriesPerPage>
    <totalPages>0</totalPages>
    <totalEntries>0</totalEntries>
  </paginationOutput>
  <itemSearchURL>http://www.ebay.co.uk/sch/i.html?_nkw=mytest1</itemSearchURL>
</findItemsAdvancedResponse>

但是使用RESPONSE-DATA-FORMAT=JSON调用相同内容时,各个元素都包含在[]中:

{"findItemsAdvancedResponse":[
  {"ack":["Success"],
   "version":["1.13.0"],
   "timestamp":["2014-11-16T20:58:14.639Z"],
   "searchResult":[
    {"@count":"0"}],
   "paginationOutput":[
     {"pageNumber":["0"],
      "entriesPerPage":["100"],
      "totalPages":["0"],
      "totalEntries":["0"]}],
   "itemSearchURL":["http:\/\/www.ebay.co.uk\/sch\/i.html?&_nkw=mytest1"]
  }]
}

这似乎使得使用Javascript提取结果变得很痛苦,例如:

response.findItemsAdvancedResponse[0].paginationOutput[0].pageNumber[0]

我在这里做错了什么或做错了什么? (如果不是,将考虑以XML格式请求结果并使用XML =&gt; JSON转换工具...)

5 个答案:

答案 0 :(得分:2)

似乎没有人对此感到困扰?

我正在使用AngularJS,我希望将Ebay API作为后端。我必须编写一个$resource interceptor来折叠所有只有1个子节点的数组来删除冗余的[]括号。

通用拦截器可以优雅地解决这个 然而我确实认为这是一个错误。

我在这里就Ebay开发者表单提问:https://forums.developer.ebay.com/questions/16385/why-does-search-return-json-items-as-array.html#answer-16386

我在易趣论坛上引用了这个页面 - 希望能帮助别人。

编辑:

......为了完整,here is the code I used。它可能不漂亮,但它对我有用。 YMMV

var resp = {"findItemsAdvancedResponse":[
   {"ack":["Success"],
    "version":["1.13.0"],
    "timestamp":["2014-11-16T20:58:14.639Z"],
    "searchResult":[
     {"@count":"0"}],
    "paginationOutput":[
      {"pageNumber":["0"],
       "entriesPerPage":["100"],
       "totalPages":["0"],
       "totalEntries":["0"]}],
    "itemSearchURL":["http:\/\/www.ebay.co.uk\/sch\/i.html?&_nkw=mytest1"]
   }]
 };

var flatten = function( obj ) {
    var ret = {};

  if( String === obj.constructor || Number === obj.constructor ) {
    return obj;
  }

  for(var prop in obj) {
    if(!obj.hasOwnProperty(prop)) continue;

    if( String === obj[prop].constructor || Number === obj[prop].constructor ) {
        ret[prop] = obj[prop];
      continue;
    }

    if( Object.prototype.toString.call( obj[prop] ) === '[object Array]' ) {
      if( obj[prop].length==0 )
        ret[prop] = null;
      if( obj[prop].length==1 && "0" in obj[prop] ) {
        ret[prop] = flatten(obj[prop][0]);
      } else {
        ret[prop] = flatten(obj[prop]);
      }
      continue; // skip below: all arrays are Objects...!
    }

    if( Object === obj[prop].constructor ) {
      ret[prop] = flatten( obj[prop] );
      continue;
    }

  }
  return ret;
};

console.log( resp );
resp = flatten( resp );
console.log( resp );
console.log( resp.findItemsAdvancedResponse.ack );

答案 1 :(得分:1)

这与DerekC's解析函数非常相似,速度要快得多。它适用于简单地查找具有Array.isArray()和长度为1的数组的元素,其值不是对象。没有什么花哨,超级干净和超快。

该函数名为ebayFormat,位于DerekC使用的同一响应对象下方。

var resp = {"findItemsAdvancedResponse":[
   {"ack":["Success"],
    "version":["1.13.0"],
    "timestamp":["2014-11-16T20:58:14.639Z"],
    "searchResult":[
     {"@count":"0"}],
    "paginationOutput":[
      {"pageNumber":["0"],
       "entriesPerPage":["100"],
       "totalPages":["0"],
       "totalEntries":["0"]}],
    "itemSearchURL":["http:\/\/www.ebay.co.uk\/sch\/i.html?&_nkw=mytest1"]
   }]
 };

  function ebayFormat(item) {
    if (typeof item === 'object') {
      if (Array.isArray(item) && item.length === 1 && typeof item[0] !== 'object') item = item[0];
      else {
        var keys = Object.keys(item),
          i = 0,
          len = keys.length;
        for (; i < len; i++) {
          if (typeof item[keys[i]] === 'object') item[keys[i]] = ebayFormat(item[keys[i]]);
        }
      }
    }
    return item;
  }

console.log( resp );
resp = ebayFormat( resp );
console.log( resp );
console.log( resp.findItemsAdvancedResponse.ack );

答案 2 :(得分:1)

我遇到了同样的问题,我做了一个递归函数来解决它(当数组长度= 1并且不排除时删除数组)

objJsonFromEbay = findAndCorrect(objJsonFromEbay);

    function findAndCorrect(obj){

        let o = obj,
            exclu = ['item'];

        for (const key in o) {
            if (o.hasOwnProperty(key)) {
                const val = o[key];

                if(Array.isArray(val) && val.length == 1){
                    if(exclu.indexOf(key) == -1)
                        o[key] = val[0];
                    o[key] = findAndCorrect(o[key]);
                }else if(!Array.isArray(val) && typeof val == 'object'){                        
                    o[key] = findAndCorrect(val);
                }
            }
        }
        return o;
    }

排除是您希望以Array格式保留的每个元素的数组。 如果你用它来获取你期望在数组中的产品或其他数据

,可能会很有用

答案 3 :(得分:1)

我遇到了同样的问题,并且很好奇,如果我选择使用XML响应与JSON响应,并在返回的数据上使用XML到JSON转换器,是否仍然会遇到问题-lo和beshed ,仍然是完全相同的问题。

我最终决定使用的转换器称为xml2js,它似乎在NPM上非常受欢迎(根据回答时NPM的数据,每月下载量为350万以上)。

xml2js在其explicitArray行为中有一个名为parseString的选项,其行为与文档记录相同:

  

如果为true,则始终将子节点放入数组中;否则,仅当存在多个数组时,才会创建一个数组。

此行为似乎可以模仿此处列出的一些答案,但是由于它是广泛使用的社区解决方案的一部分,因此与自己开发的解决方案相比,我感到更自在。

实际上,这看起来很简单:

import { parseString as xml2js } from 'xml2js';

...

xml2js(someXmlString, { explicitArray: false }, (err, results) => {
  // do something with `results`
});

https://www.npmjs.com/package/xml2js

答案 4 :(得分:-6)

这是JSON。您对JSON的期待是什么样的? : - )

{"findItemsAdvancedResponse":[
  {"ack":["Success"],
   "version":["1.13.0"],
   "timestamp":["2014-11-16T20:58:14.639Z"],
   "searchResult":[
    {"@count":"0"}],
   "paginationOutput":[
     {"pageNumber":["0"],
      "entriesPerPage":["100"],
      "totalPages":["0"],
      "totalEntries":["0"]}],
   "itemSearchURL":["http:\/\/www.ebay.co.uk\/sch\/i.html?&_nkw=mytest1"]
  }]
}

尝试转到http://jsonviewer.stack.hu/并将JSON字符串粘贴到&#34; Text&#34; -section并点击&#34; Viewer&#34;用于可视化表示JSON数据的选项卡。

您可能想访问有关JSON(JavaScript Object Notation)的维基百科文章: http://en.wikipedia.org/wiki/JSON#Data_types.2C_syntax_and_example