使用 Saxon-JS 及其全局 Javascript 函数命名空间在 XSL 中调用 jQuery-UI 组件?

Posted

技术标签:

【中文标题】使用 Saxon-JS 及其全局 Javascript 函数命名空间在 XSL 中调用 jQuery-UI 组件?【英文标题】:Calling jQuery-UI components in XSL using Saxon-JS and its global Javascript function namespace? 【发布时间】:2017-12-19 23:11:42 【问题描述】:

与this 问题相关,您可以从使用 Saxon-JS 在浏览器中运行的 XSL 2.0 转换调用 javascript 函数。但我似乎无法调用 jQuery-UI 调用。我唯一的想法是,这可能是一个时间问题,jQuery 选择器找不到目标对象的 ID,因为 Saxon-JS 尚未将其渲染到 DOM。

下面是我的简单测试...

XML...

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <date month="7" day="17" year="2017"/>
</data>

XSL...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:js="http://saxonica.com/ns/globalJS"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="html" indent="yes"/>
    <xsl:template match="/">
        <xsl:result-document href="#header">
            <hr/>
        </xsl:result-document>
        <xsl:result-document href="#editor">
            <table border="1">
                <tr bgcolor="#999999">
                    <th colspan="2">Form</th>
                </tr>
                <xsl:apply-templates select="data/date"/>
            </table>
        </xsl:result-document>
        <xsl:result-document href="#footer">
            <hr/>
        </xsl:result-document>
    </xsl:template>
    <xsl:template match="date">
        <tr>
            <td>Date:</td>
            <td>
                <xsl:variable name="currentValue"><xsl:value-of select="@month"/><xsl:text>/</xsl:text><xsl:value-of select="@day"/><xsl:text>/</xsl:text><xsl:value-of select="@year"/></xsl:variable>
                <xsl:value-of select="$currentValue"/>
                <br/>
                <input type="text" id="datepicker"/>

                <xsl:value-of select="js:initDP('#datepicker','7/17/2017')"/>

            </td>
        </tr>
    </xsl:template>
</xsl:stylesheet> 

HTML...

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>XSLT-JS-UI</title>
        <link rel="stylesheet" type="text/css" href="js/jquery-ui.min.css">
        <script type="text/javascript" src="js/jquery.min.js"></script>
        <script type="text/javascript" src="js/jquery-ui.min.js"></script>
        <script type="text/javascript" language="javascript" src="js/SaxonJS.min.js"></script>
        <script type="text/javascript" language="javascript" src="js/test.js"></script>
    </head>
    <body>
    <div id="header"></div>
    <div id="editor"></div>
    <div id="footer"></div>
    <input type="text" id="testDP"/>
    <br/>
    <button onclick="initDP('#testDP','7/17/1961')">picker</button>
    </body>
</html>

Javascript...

//=====================================
function initDP(id,init)
    
    $(id).datepicker();
    $(id).datepicker("setDate",init);
     
//=====================================
$(document).ready(function()
    
    SaxonJS.transform(
        stylesheetLocation: "test.sef.xml",
        sourceLocation: "test.xml"
        );
    );
//=====================================

包括对 initDP 的 HTML 调用(初始化 jQuery 日期选择器)和对其的 XSL 调用。 HTML 工作正常,XSL 静默失败。

【问题讨论】:

我希望 Michael Kay 能在某个地方提供帮助。 【参考方案1】:

您的 xsl:value-of Javascript 调用似乎在创建结果元素或至少插入到文档中之前进行了评估。

对我有用的是在input 之后简单地放置一个script 结果元素,即时创建Javascript 代码:

<xsl:template match="date">
    <tr>
        <td>Date:</td>
        <td>
            <xsl:variable name="currentValue" select="string-join((@month, @day, @year), '/')"/>
            <xsl:value-of select="$currentValue"/>
            <br/>
            <input type="text" id="datepickerposition()"/>

            <script xsl:expand-text="yes">initDP('#datepickerposition()', '$currentValue')</script>

        </td>
    </tr>
</xsl:template>

通过文件系统和 HTTP 上的 Firefox 和 HTTP 上的 Chrome 成功测试(Chrome 默认情况下不对文件系统执行 XMLHttpRequest,因此文件系统上的 Saxon-JS 不起作用)。 Edge 似乎没有执行 XSLT,并在 SaxonJS.min.js (1,11772) 中给出了两个“SCRIPT5022: XError: Misplaced or malformed XML”错误,IE 似乎执行了样式表,但似乎没有执行内联脚本.在线示例https://martin-honnen.github.io/xslt/2017/ui-test1.html。

我现在还成功地使用 Firefox、Chrome 和 Internet Explorer 测试了一种不同的方法 (https://martin-honnen.github.io/xslt/2017/ui-test2.xsl),它使用 ixsl:schedule-action 调用模板,然后使用 js:initDP 代替内联的 script 结果元素:

<xsl:template match="date">
    <tr>
        <td>Date:</td>
        <td>
            <xsl:variable name="currentValue" select="string-join((@month, @day, @year), '/')"/>
            <xsl:value-of select="$currentValue"/>
            <br/>
            <input type="text" id="datepickerposition()"/>
            <ixsl:schedule-action wait="1">
                <xsl:call-template name="init-datepicker">
                    <xsl:with-param name="id" select="'#datepicker' || position()"/>
                    <xsl:with-param name="value" select="$currentValue"/>
                </xsl:call-template>
            </ixsl:schedule-action>                
        </td>
    </tr>
</xsl:template>

<xsl:template name="init-datepicker">
    <xsl:param name="id" as="xs:string"/>
    <xsl:param name="value" as="xs:string"/>
    <!--<xsl:sequence select="trace(js:initDP($id, $value), 'init-datepicker called for ' || $id || ' at ' || current-dateTime())"/>-->
    <xsl:sequence select="js:initDP($id, $value)"/>
</xsl:template>

Edge 问题似乎与 Saxon-JS 和 JQuery UI 交互的问题无关,而是似乎是由当前 Edge 版本的 Javascript 引擎中的错误引起的,请参阅https://github.com/Microsoft/ChakraCore/issues/3366,其中Saxon-JS 代码在检查放错位置的 XML 声明时遇到。如果我删除 XML 输入和 Saxon 的 SEF 包文件中的 XML 声明,那么 https://martin-honnen.github.io/xslt/2017/ui-test4.html 在 Edge 中可以正常工作,并且 Saxon-JS 代码不会遇到 Edge Javascript 错误。

【讨论】:

我认为这是一个时间问题,但我没有想到内联脚本调用。谢谢。

以上是关于使用 Saxon-JS 及其全局 Javascript 函数命名空间在 XSL 中调用 jQuery-UI 组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Node 中使用 saxon-js 处理 XPath 表达式

使用 Saxon-JS 识别 XSLT 转换的性能瓶颈

Saxon-js 是不是对 xsl:param 执行 XML 语法检查?

如果 DOM classList 包含特定类,请检查 Saxon-JS 2.1

遍历 Saxon-JS 序列

如何通过 Saxon-JS 调整图像大小?