使用JavaScript查询XML时获取title、link返回undefined如何解决
问题根因
代码返回undefined是多个错误叠加导致:
document.evaluate返回的是XPathResult对象,不是可迭代节点列表,直接用展开运算符[...]无法获取到实际节点,拿到的永远是空数组。- 方法名拼写错误:调用时写的
evalute少了字母a,正确方法名是evaluate,拼写错误会直接触发JS报错。 evaluate调用缺少必填的结果类型参数,也没有调用对应API提取实际的文本/属性值,直接输出XPathResult实例自然拿到undefined。- 外层没有等待
rss.map里的异步请求执行完成,就提前拼接完HTML插入DOM,即使解析逻辑正确,内容还没拉取完成就已经完成渲染,拿不到数据。 - XPath匹配条目用的是
//entry(Atom feed的条目标签),Reddit返回的是标准RSS 2.0格式,条目标签为<item>,匹配规则不对根本选不到内容节点。
修正后可运行代码
(async () => { const rss = [ 'https://reddit.com/r/news.rss', ]; let htm = '<section id="feed">'; // 等待所有源拉取、解析完成再执行后续渲染 await Promise.all(rss.map(async feed => { console.log('feed', feed); let xml = ''; try { // 对feed地址做编码,避免特殊字符导致代理请求失败 const res = await fetch('https://api.allorigins.win/raw?url='+encodeURIComponent(feed)); xml = await res.text(); console.log('xml', xml); } catch(err) { console.error(err); return; } const doc = new window.DOMParser().parseFromString(xml, "application/xml"); // 兼容RSS的<item>和Atom的<entry>两种条目格式 const xpathResult = doc.evaluate('//item | //entry', doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); const items = []; for (let i = 0; i < xpathResult.snapshotLength; i++) { items.push(xpathResult.snapshotItem(i)); } console.log('items: ', items); items.forEach(item => { // 提取标题文本 const titleResult = doc.evaluate('./title/text()', item, null, XPathResult.STRING_TYPE, null); const title = titleResult.stringValue.trim(); // 兼容两种格式的链接提取:RSS直接存<link>文本,Atom存在link标签的href属性 let link = ''; const rssLinkResult = doc.evaluate('./link/text()', item, null, XPathResult.STRING_TYPE, null); if (rssLinkResult.stringValue.trim()) { link = rssLinkResult.stringValue.trim(); } else { const atomLinkResult = doc.evaluate('./link/@href', item, null, XPathResult.STRING_TYPE, null); link = atomLinkResult.stringValue.trim(); } console.log('link: ', link); console.log('title:', title); htm += ` <div class="item"><a href="${link}">${title}</a></div> `; }); })); htm += '</section>'; document.body.insertAdjacentHTML('beforeend', htm); })();
关键改动说明
- 所有XPath调用明确指定结果类型:取节点列表用
ORDERED_NODE_SNAPSHOT_TYPE遍历拿实际节点,取文本/属性值直接用STRING_TYPE拿字符串结果,不需要多层嵌套调用evaluate。 - 用
Promise.all包裹所有异步feed处理逻辑,确保数据拉取、解析全部完成后再拼接最终HTML插入DOM。 - 条目匹配规则兼容RSS、Atom两种主流feed格式,不需要手动区分数据源格式。
- 修正了方法名拼写错误,对请求的目标地址做URL编码避免请求异常。
内容的提问来源于stack exchange,提问作者chovy
相关产品推荐
相关产品推荐

