节点请求模块:将XML解析为JSON

时间:2018-10-02 13:21:46

标签: json node.js xml node-request

直到最近,我一直在使用node request模块来获取XML数据,然后通过XML到JSON转换器运行该XML。我偶然发现,如果我将json: true设置为选项(即使知道端点返回的是XML,而不是JSON),我实际上是在获取JSON:

var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'stackoverflow question (https://stackoverflow.com/q/52609246/4070848)' } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
request(options, function (error, response, body) {
    console.log(`body for ${options.uri}: ${JSON.stringify(body)}`);
});

上述调用返回JSON,而raw URL实际上正在发送XML。当然,使用json: false返回的数据是XML:

var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'stackoverflow question (https://stackoverflow.com/q/52609246/4070848)' } };
options.uri = 'https://api.met.no/weatherapi/locationforecast/1.9/?lat=40.597&lon=-74.26';
options.json = false; // <<--- the only difference in the request
request(options, function (error, response, body) {
    console.log(`body for ${options.uri}: ${body}`);
});

所以我以为“很方便”,直到我用different URL that also returns XML尝试了同样的技巧,在这种情况下,尽管使用了相同的请求选项,返回的数据仍然是XML:

var request = require('request');
var options = { gzip: true, json: true, headers: { 'User-Agent': 'stackoverflow question (https://stackoverflow.com/q/52609246/4070848)' } };
options.uri = 'https://graphical.weather.gov/xml/SOAP_server/ndfdXMLclient.php?whichClient=NDFDgen&lat=40.597&lon=-74.26&product=time-series&temp=tempSubmit=Submit';
request(options, function (error, response, body) {
    console.log(`body for ${options.uri}: ${body}`);
});

这里有什么区别?如何获得后一个请求以JSON格式返回数据(这样就可以避免自己将XML转换为JSON的步骤)?也许第一个示例中的端点可以检测到请求了JSON,并且实际上返回了JSON而不是XML?

编辑,很奇怪,第一个请求现在返回XML而不是JSON,即使使用json: true也是如此。因此,也许这种行为归结于从端点发送的行为,并且即使我几个小时前发布

,他们也改变了这一行为

2 个答案:

答案 0 :(得分:1)

因此,由于该行为不可重复,因此对于您的特定问题而言,答案就没有用了,但是我认为值得指出的是,当您在$selectedGradSchool = MOGRadschool::where('Title', '=', $gradschool)->get()->first(); $aboveSelected = MOGRadschool::where('id', '<=', $selectedGradSchool->id) ->orderBy('id', 'desc') ->take('5') ->get(); $belowSelected = MOGRadschool::where('id', '>' $selectedgradSchool->id) ->take('5') ->get(); //Concatenate both results $schoolRange = $aboveSelected->concat($belowSelected); 模块上设置json:true时,它会执行一些操作为您准备的事情:

  • 将Accept标头设置为“ application / json”
  • 使用request
  • 解析响应正文
  • 带有正文的请求类型也会自动将正文序列化为JSON
  • 带有正文的请求类型也会获得Content-Type标头添加为'application / json'

所以也许他们确实更改了它,但是我已经看到很多Web服务可以根据Accept报头检测要发送的内容类型,并对某些有意义的类型(通常是XML或JSON,但有时是CSV,TXT,HTML等)。

答案 1 :(得分:0)

为了处理 XML 查询,我通常使用 request 模块做这样的事情:

import parser from "xml2json";
const resp = await rp({
  method: "POST",
  url: 'some url',
  form: {xml_query}, // set XML query to xml_query field
});
const parsedData = parser.toJson(resp, {
  object: true, // returns a Javascript object instead of a JSON string
  coerce: true, // makes type coercion.
});