如何使用 fetch api 获取 XML

How to fetch XML with fetch api

我正在尝试制作一个天气应用程序来显示一周中许多天的天气和温度。我目前正在使用 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))

我猜错误来自此函数: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))
}

使用原生 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));
}

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

首先我们安装两个模块 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

这在我的 angular 应用程序中有效

import * as xml2js from 'xml2js';

url = MY_URL;

ngOnInit(): void {
 this.getData();
}

getData(): void {
  fetch(MY_URL)
    .then(response => response.text())
    .then(data => {
      let parseString = xml2js.parseString;
      parseString(data, function (err, result) {
        console.log(result);
        console.error(err);
      });
    });
}