我正在尝试制作一个天气应用程序,显示一周中许多天的天气和温度。我目前正在使用 openweathermap api 来完成此类任务,问题是我想要的信息(即天气日期)仅采用 xml 格式。 由于我出于学术原因在 ES6(ES2015) 中重建它,我还想使用 fetch api,但由于 fetch 方法解析它,它只是传递一个错误。 那么我怎样才能获取它或者有更好的方法来做到这一点。
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))
使用原生 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));
}
我猜错误来自此函数:
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))
}
对于那些想要在 Node REPL 中测试这一点的人来说,可以使用 npm xml-js 库和 node-fetch 在 Node.js 中执行此操作。
首先我们安装两个模块 xml-js 和 node-fetch:
npm 安装 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 图”。有一些关于深度搜索对象图的技巧,可以深入查找键,例如 GitHub 上的 obj-traverse 库
这在我的角度应用程序中有效
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);
});
});
}
免责声明:这是原始接受答案的扩展答案。
正如@Jinxmcg建议的那样,要解析节点中的消息,您可以使用像fast-xml-parser这样的lib。
fast-xml-parser
软件包yarn add fast-xml-parser
const { XMLParser } = require("fast-xml-parser");
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(text => new XMLParser().parse(text))
.then(data => console.log(data));
}