如何使用 fetch api 获取 XML

Posted

技术标签:

【中文标题】如何使用 fetch api 获取 XML【英文标题】:How to fetch XML with fetch api 【发布时间】:2016-10-08 05:15:16 【问题描述】:

我正在尝试制作一个天气应用程序来显示一周中许多天的天气和温度。我目前正在为此类任务使用 openweathermap api,问题是我想要的信息(即天气日期)仅以 xml 格式提供。 由于我出于学术原因在 ES6(ES2015) 中重建它,因此我也想使用 fetch api,但由于 fetch 方法会解析它,它只会传递一个错误。 那么我该如何获取它或者mby有更好的方法来做到这一点。

let apis = 
    currentWeather:  //get user selected recomendation weather
        api:"http://api.openweathermap.org/data/2.5/forecast/daily?lat=",
        parameters: "&mode=xml&units=metric&cnt=6&APPID=/*api key*/",
        url: (lat, lon) => 
            return apis.currentWeather.api + lat + "&lon=" + lon +
                   apis.currentWeather.parameters
        
    
;
function getCurrentLoc()  
    return new Promise((resolve, reject) =>  navigator.geolocation
                                             .getCurrentPosition(resolve, reject))

function getCurrentCity(location) 
    const lat = location.coords.latitude;
    const lon = location.coords.longitude;
    return fetch(apis.currentWeather.url(lat, lon))
    .then(response => response.json())
    .then(data => console.log(data))

getCurrentLoc()
.then( coords => getCurrentCity(coords))

【问题讨论】:

【参考方案1】:

我猜错误来自这个函数:response => response.json(),因为响应不是有效的 JSON 对象(它是 XML)。

据我所知,fetch 没有原生 XML 解析器,但您可以将响应作为文本处理并使用第三方工具进行实际解析,例如 jQuery 有一个 $.parseXML() 函数。

它看起来像:

function getCurrentCity(location) 
    const lat = location.coords.latitude;
    const lon = location.coords.longitude;
    return fetch(apis.currentWeather.url(lat, lon))
        .then(response => response.text())
        .then(xmlString => $.parseXML(xmlString))
        .then(data => console.log(data))

【讨论】:

我可以确认没有用于获取的本机 XML 解析器。见developer.mozilla.org/en-US/docs/Web/API/Response#Methods。 解析 XML 的 jQuery 函数又短又甜,使用 DOMParser(),如@JukkaP 的回答:github.com/jquery/jquery/blob/…【参考方案2】:

使用原生 DOMParser getCurrentCity(location) 可以写成:

function getCurrentCity(location) 
    const lat = location.coords.latitude;
    const lon = location.coords.longitude;
    return fetch(apis.currentWeather.url(lat, lon))
        .then(response => response.text())
        .then(str => new window.DOMParser().parseFromString(str, "text/xml"))
        .then(data => console.log(data));

【讨论】:

所以DOMParser 原型只有一个记录成员parseFromString?我还以为还有parseFromStreamparseFromBlob等等…… Steve Griffith 有一个great video,显示他使用 fetch 来获取 XML(很像上面的代码)。他在a gist 中有视频中的代码。 附带说明:在谈到编程时,我不会将“伟大”和“视频”组合成一句话。 如果DOMParserwindow 的一部分(正如其名称所示),它必须仅对客户端javascript 有效。在其他情况下你会怎么做,例如在 Node.js 中?【参考方案3】:

对于那些想在 Node REPL 中测试的人来说,可以使用 npm xml-js 库和 node-fetch 在 Node.js 中执行此操作。

首先我们安装两个模块 xml-js 和 node-fetch :

npm install xml-js --save npm install node-fetch --save

将这两个包存储到 package.json 中。现在回到我们手头的问题 - 如何处理从 API 返回的 XML 数据。

考虑以下获取挪威特定气象站的示例:

const fetch = require('node-fetch');
const convert = require('xml-js');
let dataAsJson = ;

fetch('http://eklima.met.no/metdata/MetDataService?invoke=getStationsProperties&stations=68050&username=')
    .then(response => response.text())
    .then(str => 
        dataAsJson = JSON.parse(convert.xml2json(str))
    )
    .then(() => 
        console.log('Station id returned from the WS is:' + 
            `$dataAsJson.elements[0].elements[0].elements[0].elements[0].elements[0].elements
                .filter(obj =>  return obj.name == 'stnr'; )[0].elements[0].text Expecting 68050 here!`
        );
    );

我们现在得到了一个变量,该变量使用 convert 的 xml2json 方法和 JSON.parse 从 XML 数据中实际解析为 JSON 对象。如果我们想打印出对象,我们可以使用 JSON.stringify 将 JSON 对象转换为字符串。在此代码中检索站 id 仅表明需要深入扫描给定键的对象图,因为将 XML 转换为 Json 通常会提供更深的对象图,因为包装 XML 元素始终位于“ XML 对象 JSON 图”。有一些关于深度搜索对象图的提示,可以很深地寻找关键,例如obj-traverse library on GitHub

【讨论】:

这并没有给出预期的键值 JSON,而是一个带有许多额外键的复杂 JSON。

以上是关于如何使用 fetch api 获取 XML的主要内容,如果未能解决你的问题,请参考以下文章

使用 fetch、cors 时如何从 json API 获取属性?

JS fetch API:如何使用一个异步函数从多个文件中获取内容?

使用 Fetch API 发布 XML

如何在 React 中使用 fetch() API 来设置状态

我如何使用 fetch API 并在状态下存储响应?

使用 Fetch API 获取 json 格式的闪烁提要