如何在 .XSLT (英语:XSLT)

How to create a JavaScript Array inside of a .XSLT

提问人:Melifluo Comas 提问时间:10/16/2023 更新时间:10/16/2023 访问量:36

问:

所以这就是我需要 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>
JavaScript XML XSLT

评论

0赞 Michael Kay 10/16/2023
XSLT在哪里?

答:

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(例如),然后可以使用较小的运行时库,获得更好的性能和异步处理:xslt3xslt3 -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>