使用Greasemonkey脚本将javascript添加到使用XSLT转换的XML文件中 [英] Adding javascript to a XML file transformed with XSLT using a Greasemonkey script

查看:31
本文介绍了使用Greasemonkey脚本将javascript添加到使用XSLT转换的XML文件中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里回答我的问题-

As follow up to my question here - How to transform an XML file with XSLT, using a Greasemonkey script? - I'm facing another problem:

我想在XSL模板中使用一些基本的javascript函数,以控制某些div的显示.但是,无论我如何包括这些javascript函数,它们似乎都无法被识别.我已经进行了很多研究,但似乎无法解决.

I want to use some basic javascript functions in my XSL template in order to control the display of some divs. However, no matter how I include these javascript functions, they don't seem to be recognized. I already investigated a lot but I can't seem to get around it.

我尝试了两件事:

  • <script>标记中的XSL模板中添加javascript
  • 在Greasemonkey脚本本身中添加新的<script>标记
  • Adding the javascript in the XSL template in a <script> tag
  • Appending a new <script> tag in the Greasemonkey script itself

我宁愿不使用jQuery或外部JS文件(我也尝试过)以使其尽可能简单,但是如果这样可以解决问题,我愿意改变整个事情!

I would prefer not to use jQuery or an external JS file (which I also tried) to keep it as simple as possible, but if that would solve the problem I'm open to change the whole thing!

无论哪种情况,当我调用该函数时,都会得到一个ReferenceError: x is not defined.我确实看到javascript代码很好地位于了最终的HTML结果中.当我使用Firebug附加具有简单功能的新<script>标记时,该标记会向纯HTML页面发出"hello"警报,然后它可以完美运行.只有在XSLT转换之上完成此操作后,事情才会出错(为简单起见,我仅使用一个简单的函数来显示警报框).

In either case when I call the function I get a ReferenceError: x is not defined. I do see that the javascript code sits nicely in the final HTML result though. When I use Firebug to append a new <script> tag with a simple function that alerts "hello" to a plain html page then it works perfectly. It's only when this is done on top of a XSLT transformation things go wrong (for the sake of simplicity I'm just using a simple function to show an alert box).

这是我的示例数据:

  <?xml version="1.0" encoding="utf-8"?>
  <Results>
      <Result>
          <Listings total="2">
              <Res>
                  <Result index="0">
                      <id>123456</id>
                      <name>My Business</name>
                      <category>Restaurants</category>
                      <phone>9872365</phone>
                  </Result>
              </Res>
              <Res>
                  <Result index="1">
                      <id>876553</id>
                      <name>Some Other Business</name>
                      <category>Restaurants</category>
                      <phone>9834756</phone>
                  </Result>
              </Res>
          </Listings>
      </Result>
  </Results>


这是我第一次在<head>标签中添加<script>标签的尝试:


Here's the first attempt where I just added a <script> tag in the <head> tag:

// ==UserScript==
// @name        _Test XML Renderer
// @description stylesheet for xml results
// @include     *
// @grant       none
// ==/UserScript==

var xsl_str = '<?xml version="1.0" encoding="utf-8"?>\n\
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">\n\
    <xsl:output method="html"/>\n\
    <xsl:template match="/">\n\
        <html>\n\
            <head><script type="text/javascript">function hello() {alert("hello")};</script></head>\n\
            <body>\n\
                <table id="results" border="1" cellspacing="0" cellpadding="0">\n\
                    <thead>\n\
                        <tr>\n\
                            <th class="name">id</th>\n\
                            <th class="name">category ID</th>\n\
                            <th class="name">name</th>\n\
                            <th class="name">phone</th>\n\
                        </tr>\n\
                    </thead>\n\
                    <tbody>\n\
                        <xsl:for-each select="Results/Result/Listings/Res">\n\
                            <tr>\n\
                                <td class="small" width="120">\n\
                                    <a href="#" onclick="hello()"><xsl:value-of select="Result/id"/></a>\n\
                                </td>\n\
                                <td class="small" width="120">\n\
                                    <xsl:value-of select="Result/category"/>\n\
                                </td>\n\
                                <td class="small" width="120">\n\
                                    <xsl:value-of select="Result/name"/>\n\
                                </td>\n\
                                <td class="small" width="120">\n\
                                    <xsl:value-of select="Result/phone"/>\n\
                                </td>\n\
                            </tr>\n\
                        </xsl:for-each>\n\
                    </tbody>\n\
                </table>\n\
            </body>\n\
        </html>\n\
    </xsl:template>\n\
</xsl:stylesheet>\n\
';

var processor   = new XSLTProcessor ();
var dataXSL     = new DOMParser ().parseFromString (xsl_str, "text/xml");

processor.importStylesheet (dataXSL);

var newDoc      = processor.transformToDocument (document);

//-- These next lines swap the new, processed doc in for the old one...
window.content  = newDoc;

document.replaceChild (
    document.importNode (newDoc.documentElement, true),
    document.documentElement
);


这是我在XSL模板之外添加"hello"功能的另一种尝试:


Here's my other attempt where I add the "hello" function outside the XSL template:

// ==UserScript==
// @name        _Test XML Renderer
// @description stylesheet for xml results
// @include     *
// @grant       none
// ==/UserScript==

var xsl_str = '<?xml version="1.0" encoding="utf-8"?>\n\
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">\n\
    <xsl:output method="html"/>\n\
    <xsl:template match="/">\n\
        <html>\n\
            <head></head>\n\
            <body>\n\
                <table id="results" border="1" cellspacing="0" cellpadding="0">\n\
                    <thead>\n\
                        <tr>\n\
                            <th class="name">id</th>\n\
                            <th class="name">category ID</th>\n\
                            <th class="name">name</th>\n\
                            <th class="name">phone</th>\n\
                        </tr>\n\
                    </thead>\n\
                    <tbody>\n\
                        <xsl:for-each select="Results/Result/Listings/Res">\n\
                            <tr>\n\
                                <td class="small" width="120">\n\
                                    <a href="#" onclick="hello()"><xsl:value-of select="Result/id"/></a>\n\
                                </td>\n\
                                <td class="small" width="120">\n\
                                    <xsl:value-of select="Result/category"/>\n\
                                </td>\n\
                                <td class="small" width="120">\n\
                                    <xsl:value-of select="Result/name"/>\n\
                                </td>\n\
                                <td class="small" width="120">\n\
                                    <xsl:value-of select="Result/phone"/>\n\
                                </td>\n\
                            </tr>\n\
                        </xsl:for-each>\n\
                    </tbody>\n\
                </table>\n\
            </body>\n\
        </html>\n\
    </xsl:template>\n\
</xsl:stylesheet>\n\
';

var processor   = new XSLTProcessor ();
var dataXSL     = new DOMParser ().parseFromString (xsl_str, "text/xml");

processor.importStylesheet (dataXSL);

var newDoc      = processor.transformToDocument (document);

var script = "function hello() {alert('hello')};";
var newElem = newDoc.createElement('script');
newElem.type = 'text/javascript';
newElem.appendChild(newDoc.createTextNode(script));
newDoc.getElementsByTagName('head').item(0).appendChild(newElem);

//-- These next lines swap the new, processed doc in for the old one...
window.content  = newDoc;

document.replaceChild (
    document.importNode (newDoc.documentElement, true),
    document.documentElement
);

推荐答案

请勿使用onclick .用户脚本的数量增加了三倍,因为存在其他范围和/或沙箱冲突.

Don't use onclick. This goes triple for userscripts, as there are additional scope and/or sandbox conflicts.

此外,尝试将JS添加到XSLT文件/文本中也是一个糟糕的主意,在这种情况下也不需要脚本注入.

Also, it's a poor idea to try and add JS into the XSLT file/text, and there is no need for script injection in this case either.

使用脚本来执行您需要考虑的所有JS操作.例如:

Use the script to do whatever JS manipulation you have in mind. For example:

// ==UserScript==
// @name        _XML Renderer with javascript functionality
// @description Stylesheet and javascript for xml results
// @include     http://YOUR_SERVER.COM/YOUR_PATH/*.xml
// @resource    xslFile  Q_17998446_transform.xsl
// @grant       GM_getResourceText
// ==/UserScript==

var xsl_str     = GM_getResourceText ("xslFile");
var processor   = new XSLTProcessor ();
var dataXSL     = new DOMParser ().parseFromString (xsl_str, "text/xml");

processor.importStylesheet (dataXSL);

var newDoc      = processor.transformToDocument (document);

//-- These next lines swap the new, processed doc in for the old one...
window.content  = newDoc;

document.replaceChild (
    document.importNode (newDoc.documentElement, true),
    document.documentElement
);

//-- Use JS to smarten-up the new document.
var firstCols   = document.querySelectorAll ("#results td:first-child");

for (var J = firstCols.length - 1;  J >= 0;  --J) {
    var tdNode = firstCols[J];
    tdNode.style.cursor = "pointer";
    tdNode.addEventListener ("click", clickCellHandler, false);
}

function clickCellHandler (zEvent) {
    var cellContents = zEvent.target.textContent.trim ();

    alert ('The clicked cell contains "' + cellContents + '".');
}

其中Q_17998446_transform.xsl是保存在与安装脚本相同的文件夹中的文件(您可能需要卸载并重新安装脚本).

where Q_17998446_transform.xsl is a file saved in the same folder from where you install your script (you may need to uninstall, and reinstall, the script).

Q_17998446_transform.xsl包含以下内容:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="html"/>
    <xsl:template match="/">
        <html>
            <head></head>
            <body>
                <table id="results" border="1" cellspacing="0" cellpadding="0">
                    <thead>
                        <tr>
                            <th class="name">id</th>
                            <th class="name">category ID</th>
                            <th class="name">name</th>
                            <th class="name">phone</th>
                        </tr>
                    </thead>
                    <tbody>
                        <xsl:for-each select="Results/Result/Listings/Res">
                            <tr>
                                <td class="small" width="120">
                                    <xsl:value-of select="Result/id"/>
                                </td>
                                <td class="small" width="120">
                                    <xsl:value-of select="Result/category"/>
                                </td>
                                <td class="small" width="120">
                                    <xsl:value-of select="Result/name"/>
                                </td>
                                <td class="small" width="120">
                                    <xsl:value-of select="Result/phone"/>
                                </td>
                            </tr>
                        </xsl:for-each>
                    </tbody>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>



当您在适当的XML文件上运行该脚本时,它会在第一个表列(无标题)中添加一个点击处理程序,即"Web 2.0"方式.



When you run that script on the appropriate XML file, it adds a click-handler to the first table column (sans header) -- the "Web 2.0" way.

单击第一列单元格之一时,它会发出警报,例如:

When one of the first-column cells is clicked, it alerts, for example:

单击的单元格包含"876553".

The clicked cell contains "876553".

这篇关于使用Greasemonkey脚本将javascript添加到使用XSLT转换的XML文件中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆