简体   繁体   English

从 JavaScript 调用 Saxon-JS function 或模板

[英]Calling Saxon-JS function or template from JavaScript

I use C3 to render graphs in an HTML page that uses Saxon-JS and a (compiled, SEF) XSL stylesheet.我使用C3在 HTML 页面中呈现图形,该页面使用 Saxon-JS 和(已编译,SEF)XSL 样式表。 C3 generates an SVG image (a bar chart), and provides a possibility to respond to click events on parts of the chart (eg, a bar), with an onclick function. C3 生成 SVG 图像(条形图),并提供了响应图表部分(例如条形图)上的点击事件的可能性,具有 onclick function。

c3.generate(
  { bindto: ...
  , data:
    { type: 'bar'
    , columns: c3_columns
    , onclick: function(data, element) { ... }
    }
    ...
  })

I would like to process the click event in my XSL stylesheet.我想在我的 XSL 样式表中处理点击事件。 However:然而:

  • The onclick function is not a JavaScript event handler in the usual sense. onclick function 不是通常意义上的 JavaScript 事件处理程序。 The data parameter contains data but is not an Event instance. data参数包含数据但不是Event实例。 Also, the JavaScript event variable is undefined in the body of the onclick function.此外,JavaScript event变量在 onclick function 的正文中undefined

  • When I dispatch a custom event from the onclick function, I can not handle it in my XSL.当我从 onclick function 发送自定义事件时,我无法在我的 XSL 中处理它。 That means that when I define <xsl:template match="*" mode="ixsl:onchartclick"> , this template is not called when I dispatch a chartclick event from the onclick function.这意味着当我定义<xsl:template match="*" mode="ixsl:onchartclick">时,当我从 onclick function 发送chartclick事件时,不会调用此模板。

  • Next, I tried to call a function defined in my XSL stylesheet: <xsl:function xmlns:chart="chart" name="chart:click"> This is called from the onclick function (JavaScript) like接下来,我尝试调用在我的 XSL 样式表中定义的<xsl:function xmlns:chart="chart" name="chart:click">

     SaxonJS.XPath.evaluate("chart:click('hello chartCLick')", [], { namespaceContext: {'chart': 'chart'} });

    Although the onclick function is called, the XSL function isn't;尽管调用了 onclick function,但 XSL function 没有调用; All I get in the browser console is "Unknown function Q{chart}click()".我在浏览器控制台中得到的只是“Unknown function Q{chart}click()”。

This scenario is a bit complex, but I will include two simplified code samples that hopefully show what I am trying to do.这个场景有点复杂,但我将包括两个简化的代码示例,希望能展示我正在尝试做的事情。

In the Javascript I have the onclick handler.在 Javascript 中,我有 onclick 处理程序。

function chartClickHandler(data, element) {
  // Show the contents of the data.
  console.log(`Click on chart`);
  Object.entries(data).forEach(([k, v]) => console.log(`  ${k} : ${v}`));
  // Send a custom event.
  const event = new CustomEvent('chartclick', data);
  document.getElementsByTagName('body')[0].dispatchEvent(event);
  // Call a function in the XSL stylesheet.
  SaxonJS.XPath.evaluate(`chart:click('hello chartCLick')`, [],
    { namespaceContext: {'chart' : 'chart'}
    });
}

This is called from the HTML. For simplicity, I don't use C3, but:这是从 HTML 调用的。为简单起见,我不使用 C3,但是:

<button onclick="chartClickHandler({x: 1, y: 2}, this)">test</button>

In the XSL stylesheet that is given to Saxon-JS I have:在提供给 Saxon-JS 的 XSL 样式表中,我有:

  <xsl:template match="body" mode="ixsl:onchartclick">
    <xsl:if test="$show-debug-messages">
      <xsl:message>
        Chartclick event properties: <xsl:value-of select="ixsl:eval('Object.keys') => ixsl:apply([ixsl:event()])"/>
      </xsl:message>
    </xsl:if>
  </xsl:template>

  <xsl:function xmlns:chart="chart" name="chart:click">
    <xsl:param name="data"/>
    <xsl:message>
      Chart click data: <xsl:value-of select="serialize($data)"/>
    </xsl:message>
  </xsl:function>

As said before, all I get is如前所述,我得到的只是

Click on chart debugger eval code:3:11
  x : 1 debugger eval code:4:52
  y : 2 debugger eval code:4:52
Uncaught 
Object { message: "Unknown function Q{chart}click()", stack: ...

This example still involves many parts, but the essence of my question is in the title: How to call a Saxon-JS function or template from JavaScript. Or how to intercept custom events.这个例子仍然涉及很多部分,但我的问题的本质在标题中:How to call a Saxon-JS function or template from JavaScript. Or how to intercept custom events.

As I said in a comment, I think to call a function in an SEF you should use SaxonJS.transform({ initialFunction: 'Q{namespace-uri}function-name', functionParams: [function arguments here], ..}, ..) .正如我在评论中所说,我认为要在 SEF 中调用 function,您应该使用SaxonJS.transform({ initialFunction: 'Q{namespace-uri}function-name', functionParams: [function arguments here], ..}, ..)

Example is eg https://martin-honnen.github.io/xslt/2022/xsltFunctionCallTest2.html例如https://martin-honnen.github.io/xslt/2022/xsltFunctionCallTest2.html

Content:内容:

<html lang="en">
  <head>
    <title>Saxon-JS 2 test</title>
    <script src="../../Saxon-JS-2.3/SaxonJS2.rt.js"></script>
    <script>
    var internalStylesheet;
    document.addEventListener('DOMContentLoaded', e => {
      var options = { 
        stylesheetLocation : 'xsltFunctionCallTest1.xsl.sef.json',
        sourceLocation: 'sample1.xml',
        destination: 'appendToBody'
      };
      SaxonJS.transform(options, 'async').then(result => { internalStylesheet = result.stylesheetInternal; console.log(internalStylesheet); console.log(result); });
    });
    </script>
    <script>
      function functionCallTest1() {
       SaxonJS.transform({ destination: 'raw', stylesheetLocation : 'xsltFunctionCallTest1.xsl.sef.json', initialFunction: 'Q{http://example.com/mf}f1', functionParams: [ { x: 1, y: 'foo' }] }, 'async').then(result => console.log(result.principalResult)); 
      }
    </script>
  </head>
  <body>
    <h1>Test</h1>
  </body>
</html>

where the first transform generates eg第一个转换生成例如

<section>
  <h2>Test</h2>
  <p>Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</p>
  <input type="button" value="test"
    onclick="functionCallTest1();"/>
</section>

Caveat: in the XSLT, make sure you have visibility="public" on the XSLT xsl:function declared.警告:在 XSLT 中,确保在 XSLT xsl:function声明了visibility="public"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM