如何在XSLT中创建动态JavaScript数组获取XML票务数据
在XSLT中通过JavaScript动态获取票务数据生成数组的解决方案
问题背景
当前动画脚本依赖静态XML测试数据,需要改为从XSLT处理的XML输入中动态获取<QflowMessage/NewTickets>下的票务信息,生成newTickets数组。此前尝试fetch和<xsl:value-of>均未成功,核心需求是替换静态数据,实现动态票务数据的加载与处理。
方案一:直接从XSLT上下文XML提取数据(推荐)
XSLT本身正在处理目标XML,无需额外解析字符串,可直接将XML节点转换为JS可用的数组:
方式1:直接获取XML节点集
替换原脚本中静态xmlString、parser、newTickets的初始化代码,改为:
// 利用XPath从当前文档(XSLT处理后的XML/HTML)中获取票务节点 var xpathResult = document.evaluate('/QflowMessage/NewTickets/CallTicket', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var newTickets = []; for (var i = 0; i < xpathResult.snapshotLength; i++) { newTickets.push(xpathResult.snapshotItem(i)); }
方式2:XSLT直接生成JS对象数组
在XSLT模板中直接将XML数据序列化为JS数组对象,避免后续节点查询:
<script> var newTickets = [ <xsl:for-each select="/QflowMessage/NewTickets/CallTicket"> { NewTicket: "<xsl:value-of select="NewTicket"/>", TicketLabel: "<xsl:value-of select="TicketLabel"/>", TicketNumber: "<xsl:value-of select="TicketNumber"/>", LocationLabel: "<xsl:value-of select="LocationLabel"/>", LocationNumber: "<xsl:value-of select="LocationNumber"/>" }<xsl:if test="position() != last()">,</xsl:if> </xsl:for-each> ]; </script>
这种方式下,后续processTickets函数可直接访问对象属性(如ticket.TicketNumber),无需调用querySelector。
方案二:异步动态拉取票务数据(适用于定时更新场景)
若需从服务器定时获取最新票务数据,可修改fetch逻辑确保正确解析XML响应:
var ding = new Audio('../Style/Content/sound/ding.mp3'); var isDingPlayed = false; function startBlinking(element, duration, count) { element.style.animationName = ''; void element.offsetWidth; element.style.animationName = 'blink'; element.style.animationDuration = duration + 's'; element.style.animationIterationCount = count; if (!isDingPlayed) { ding.play(); ding.currentTime = 0; isDingPlayed = true; } } // 新增异步获取票务数据函数 async function fetchTickets() { try { // 替换为实际的票务XML接口地址 const response = await fetch('/path/to/your/tickets.xml'); if (!response.ok) throw new Error(`请求失败:${response.status}`); const xmlText = await response.text(); const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlText, 'text/xml'); return Array.from(xmlDoc.querySelectorAll('NewTickets CallTicket')); } catch (err) { console.error('获取票务数据出错:', err); return []; } } async function processTickets() { while (true) { var newTickets = await fetchTickets(); if (newTickets.length === 0) { await new Promise(resolve => setTimeout(resolve, 20000)); continue; } var ticketIndex = 0; while (ticketIndex < newTickets.length) { var ticket = newTickets[ticketIndex]; var code1 = document.getElementById('Code1-blink'); var code2 = document.getElementById('Code2-blink'); var code1label = document.getElementById('Code1-Label'); var code2label = document.getElementById('Code2-Label'); if (ticket.querySelector("NewTicket").textContent === "1") { code1.innerHTML = ticket.querySelector("TicketNumber").textContent; code2.innerHTML = ticket.querySelector("LocationNumber").textContent; code1label.innerHTML = ticket.querySelector("TicketLabel").textContent; code2label.innerHTML = ticket.querySelector("LocationLabel").textContent; startBlinking(code1, 5, 4); startBlinking(code2, 5, 4); } else { code1.innerHTML = ''; code2.innerHTML = ''; code1label.innerHTML = ''; code2label.innerHTML = ''; } await new Promise(resolve => setTimeout(resolve, 20000)); isDingPlayed = false; ticketIndex++; } } } setTimeout(processTickets, 5000);
问题排查说明
- 此前使用
<xsl:value-of select="/QflowMessage/NewTickets"/>仅能获取节点的文本内容,无法拿到完整的XML节点结构,因此无法解析为可用的票务数据。 - 若
fetch失败,需检查:接口地址是否正确、服务器响应是否为合法XML、是否存在跨域限制(可通过浏览器控制台查看报错信息)。
内容的提问来源于stack exchange,提问作者Melifluo Comas
相关产品推荐
相关产品推荐

