提问人:Melifluo Comas 提问时间:10/16/2023 更新时间:10/16/2023 访问量:36
如何在 .XSLT (英语:XSLT)
How to create a JavaScript Array inside of a .XSLT
问:
所以这就是我需要 JavaScript 在 xslt 中创建一个数组的事情,这是我执行动画的脚本,目前我有一些测试 xml 数据是一个链,但我需要是动态的而不是静态链,我尝试过获取,并放入 <XLS:value-of select=“/QflowMessage/NewTickets”>但没有检索任何数据, 目标是创建一个带有var NewTickets的数组,其中包含所有信息,有什么想法吗?
var xmlString =` <QflowMessage>
<NewTickets>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Now Serving</TicketLabel>
<TicketNumber>456201</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>608</LocationNumber>
</CallTicket>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Now Serving</TicketLabel>
<TicketNumber>ABC201</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>601</LocationNumber>
</CallTicket>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Serving</TicketLabel>
<TicketNumber>ABC8701</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>701</LocationNumber>
</CallTicket>
</NewTickets>
</QflowMessage>`;
var parser = new DOMParser();
var xml = parser.parseFromString(xmlString, "text/xml");
var newTickets = Array.from(xml.querySelector("NewTickets").querySelectorAll("CallTicket"));
var ding = new Audio('../Style/Content/sound/ding.mp3');
var isDingPlayed = false;
function startBlinking(element, duration, count) {
// Elimina la animación actual
element.style.animationName = '';
// Fuerza un reflow, esto permite reiniciar la animación
void element.offsetWidth;
// Agrega la animación
element.style.animationName = 'blink';
element.style.animationDuration = duration + 's';
element.style.animationIterationCount = count;
ding.play();
ding.currentTime = 0;
if (!isDingPlayed) {
ding.play();
ding.currentTime = 0;
isDingPlayed = true;
}
}
async function processTickets() {
var ticketIndex = 0;
while (true) {
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 {
// Si NewTicket es 0, puedes borrar los códigos o hacer algo más aquí
code1.innerHTML = '';
code2.innerHTML = '';
code1label.innerHTML = '';
code2label.innerHTML = '';
}
await new Promise(resolve => setTimeout(resolve, 20000));
isDingPlayed = false;
// Incrementa el índice del ticket y vuelve a 0 si hemos llegado al final de la lista de tickets
ticketIndex++;
if (ticketIndex >= newTickets.length) {
ticketIndex = 0;
}
}
}
setTimeout(processTickets, 5000);
</script>
答:
0赞
Martin Honnen
10/16/2023
#1
XSLT 3.0 支持将 JSON 对象和数组处理为 XDM/XPath 3.1 映射和数组;在浏览器中,您可以使用 SaxonJS(当前版本为 2.6)来使用 XSLT 3.0,完整的文档位于 https://www.saxonica.com/saxon-js/documentation2/index.html:
要运行 XSLT 3.0(从源代码),您需要一个样式表,例如
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
exclude-result-prefixes="#all">
<xsl:output method="json" indent="yes"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="array { QflowMessage/NewTickets/CallTicket ! map:merge(*!map:entry(local-name(), if (. castable as xs:double) then number() else string() )) }"/>
</xsl:template>
</xsl:stylesheet>
你可以用 JavaScript 运行它,如下所示:
const xslt = `<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
exclude-result-prefixes="#all">
<xsl:output method="json" indent="yes"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="array { QflowMessage/NewTickets/CallTicket ! map:merge(*!map:entry(local-name(), if (. castable as xs:double) then number() else string() )) }"/>
</xsl:template>
</xsl:stylesheet>`;
var xml = `<QflowMessage>
<NewTickets>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Now Serving</TicketLabel>
<TicketNumber>456201</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>608</LocationNumber>
</CallTicket>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Now Serving</TicketLabel>
<TicketNumber>ABC201</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>601</LocationNumber>
</CallTicket>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Serving</TicketLabel>
<TicketNumber>ABC8701</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>701</LocationNumber>
</CallTicket>
</NewTickets>
</QflowMessage>`;
var result = SaxonJS.XPath.evaluate(`transform(map {
'stylesheet-text' : $xslt,
'source-node' : parse-xml($xml),
'delivery-format' : 'raw'
})?output`, null, { params : { xslt : xslt, xml : xml } });
console.log(result);
<script src="https://martin-honnen.github.io/SaxonJS-2.6/SaxonJS2.js"></script>
使用 Node .js命令行工具 https://www.npmjs.com/package/xslt3 您还可以将 XSLT 源代码预编译为 SEF/JSON(例如),然后可以使用较小的运行时库,获得更好的性能和异步处理:xslt3
xslt3 -t -nogo -xsl:abovexslt.xsl -relocate:on -export:abovexslt.xsl.sef.json
const xsltSefJson = `{"N":"package","version":"30","packageVersion":"1","saxonVersion":"SaxonJS 2.6","target":"JS","targetVersion":"2","name":"TOP-LEVEL","relocatable":"true","buildDateTime":"2023-10-16T09:34:50.323+02:00","ns":"xml=~ xsl=~ xs=~ map=~","C":[{"N":"co","binds":"","id":"0","uniform":"true","C":[{"N":"template","flags":"os","module":"tickets-to-json-array.xsl","slots":"200","name":"Q{http://www.w3.org/1999/XSL/Transform}initial-template","line":"10","expand-text":"false","sType":"1FA v[*FM]","C":[{"N":"ifCall","name":"Q{http://www.w3.org/2005/xpath-functions/array}_from-sequence","sType":"1FA v[*FM]","ns":"= xml=~ fn=~ xsl=~ xs=~ map=~ ","role":"body","line":"11","C":[{"N":"forEach","C":[{"N":"docOrder","C":[{"N":"slash","op":"/","C":[{"N":"slash","op":"/","C":[{"N":"axis","name":"child","nodeTest":"*NE nQ{}QflowMessage"},{"N":"axis","name":"child","nodeTest":"*NE nQ{}NewTickets"}]},{"N":"axis","name":"child","nodeTest":"*NE nQ{}CallTicket"}]}]},{"N":"ifCall","name":"Q{http://www.w3.org/2005/xpath-functions/map}merge","C":[{"N":"forEach","C":[{"N":"axis","name":"child","nodeTest":"*NE"},{"N":"ifCall","name":"Q{http://www.w3.org/2005/xpath-functions/map}entry","C":[{"N":"fn","name":"local-name","C":[{"N":"dot"}]},{"N":"choose","C":[{"N":"castable","flags":"a","as":"AO","C":[{"N":"dot"}]},{"N":"fn","name":"number","C":[{"N":"atomSing","diag":"0|0||number","card":"?","C":[{"N":"dot"}]}]},{"N":"true"},{"N":"fn","name":"string","C":[{"N":"dot"}]}]}]}]}]}]}]}]}]},{"N":"co","binds":"","id":"1","C":[{"N":"mode","onNo":"TC","flags":"","patternSlots":"0","prec":"","C":[{"N":"templateRule","rank":"0","prec":"0","seq":"0","ns":"xml=~ xsl=~ xs=~ map=~","minImp":"0","flags":"s","slots":"200","line":"10","module":"tickets-to-json-array.xsl","expand-text":"false","match":"/","prio":"-0.5","matches":"ND","C":[{"N":"p.nodeTest","role":"match","test":"ND","sType":"1ND","ns":"= xml=~ fn=~ xsl=~ xs=~ map=~ "},{"N":"ifCall","name":"Q{http://www.w3.org/2005/xpath-functions/array}_from-sequence","sType":"1FA v[*FM]","ns":"= xml=~ fn=~ xsl=~ xs=~ map=~ ","role":"action","line":"11","C":[{"N":"forEach","C":[{"N":"docOrder","C":[{"N":"slash","op":"/","C":[{"N":"slash","op":"/","C":[{"N":"axis","name":"child","nodeTest":"*NE nQ{}QflowMessage"},{"N":"axis","name":"child","nodeTest":"*NE nQ{}NewTickets"}]},{"N":"axis","name":"child","nodeTest":"*NE nQ{}CallTicket"}]}]},{"N":"ifCall","name":"Q{http://www.w3.org/2005/xpath-functions/map}merge","C":[{"N":"forEach","C":[{"N":"axis","name":"child","nodeTest":"*NE"},{"N":"ifCall","name":"Q{http://www.w3.org/2005/xpath-functions/map}entry","C":[{"N":"fn","name":"local-name","C":[{"N":"dot"}]},{"N":"choose","C":[{"N":"castable","flags":"a","as":"AO","C":[{"N":"dot"}]},{"N":"fn","name":"number","C":[{"N":"atomSing","diag":"0|0||number","card":"?","C":[{"N":"dot"}]}]},{"N":"true"},{"N":"fn","name":"string","C":[{"N":"dot"}]}]}]}]}]}]}]}]}]}]},{"N":"overridden"},{"N":"output","C":[{"N":"property","name":"Q{http://saxon.sf.net/}stylesheet-version","value":"30"},{"N":"property","name":"method","value":"json"},{"N":"property","name":"indent","value":"yes"}]},{"N":"decimalFormat"}],"Σ":"fa30aa34"}`;
var xml = `<QflowMessage>
<NewTickets>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Now Serving</TicketLabel>
<TicketNumber>456201</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>608</LocationNumber>
</CallTicket>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Now Serving</TicketLabel>
<TicketNumber>ABC201</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>601</LocationNumber>
</CallTicket>
<CallTicket>
<NewTicket>1</NewTicket>
<TicketLabel>Serving</TicketLabel>
<TicketNumber>ABC8701</TicketNumber>
<LocationLabel>InfoApproach</LocationLabel>
<LocationNumber>701</LocationNumber>
</CallTicket>
</NewTickets>
</QflowMessage>`;
async function testXslt() {
var result = await SaxonJS.transform( {
stylesheetText : xsltSefJson,
sourceNode: await SaxonJS.getResource({type : 'xml', text : xml }),
destination : 'raw'
}, 'async');
console.log(result.principalResult);
}
testXslt()
<script src="https://martin-honnen.github.io/SaxonJS-2.6/SaxonJS2.rt.js"></script>
评论