jquery 转换 xsl xml 问题..在 IE 中工作正常,在 FireFox 中失败

发布于 2024-11-25 16:14:00 字数 7131 浏览 0 评论 0原文

根据记录,我使用的是 Windows XP SP3,运行 FireFox 5 和 IE 8。

我正在开发一个使用石器时代代码的项目,试图重构它,使其现代化。它仅适用于 IE,并且大量使用 XML 和 XSLT。

加载页面时,内容会使用 XSLT 和 XML 预处理动态放置在 div 内。该内容由 img、地图和输入标记组成,这些标记是从 XSL 文件中检索的。这在 Firefox 和 Internet Explorer 中都可以正常工作;它加载良好,图像显示正确,具有正确的映射,利用 img 上的 usemap 属性。

有一个选择框允许用户加载不同的图像——这就是我遇到问题的地方。当用户在选择框中进行选择时,它会镜像页面首次加载时的步骤:XSLT,通过 XML 对象和 XML 文件。本质上,div 的内容被重新加载。

这在 Internet Explorer (IE) 中运行良好;然而,FireFox 根本没有改变。

我找到了一个 jquery 转换插件,这是我正在使用的代码行:

function TransformXML()
{
  var html = null;
  var XML_Image = null;
  // Load XML document into XML_Image and do manipulation on it before transformation
  // ...
  // Further down in the function..

  if (document.implementation && document.implementation.createDocument)
  {
    html = $.transform({async:false, xmlobj:XML_Image, xsl:"xsl/ImageData.xsl"});
    document.getElementById("DivContent").appendChild(html);
  }
  else
  {
    html = $.transform({async:false, xmlobj:XML_Image, xsl:"xsl/ImageData.xsl"});
    document.getElementById("DivContent").innerHTML = html;
  }
}

正如我所说,IE 工作正常。不幸的是,html 变量值为空(FireBug 报告“”)。可能是什么问题???

XSL 文件确实使用了 XSL:import,但是 jquery 转换插件在 IE 上工作得很好;不过,我不知道 FireFox 是否不喜欢它(FireBug 在调试 XSLT 方面很糟糕)。

预先感谢您的帮助!

更新

我已经确定它与 XSL 文件有关。我尝试使用 jquery 转换插件中的示例 XML 和 XSL 文件,它起作用了。然后,我尝试使用 XML 对象、XML_Image 和示例 XSL 文件,它也起作用了。最后,我尝试使用示例 XML 文件和我的 XSL 文件 ImageData.xsl,但它不起作用。但是,我不确定 XSL 文件有什么问题。

UPDATE2

嗯,我认为这是 XSL 文件的问题。如下:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>

  <xsl:template name="chgBR">

    <xsl:param name="str"/>
    <xsl:choose>
      <xsl:when test='$str = ""'>
        <br/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$str"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

<xsl:template name="replace">
  <xsl:param name="str"/>
  <xsl:param name="src"/>
  <xsl:param name="dst"/>
  <xsl:if test='$str != ""'>
    <xsl:choose>
    <xsl:when test='substring-before( $str, $src ) = "" '>
      <xsl:value-of select='$str'/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select='substring-before( $str, $src )'/>
    <xsl:choose>
      <xsl:when test='$dst = "&lt;br/&gt;"'>
        <xsl:element name="br"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select='$dst'/>
      </xsl:otherwise>
      </xsl:choose>
      <xsl:call-template name='replace'>
        <xsl:with-param name='str' select='substring-after( $str,$src )'/>
        <xsl:with-param name='src' select='$src'/>
        <xsl:with-param name='dst' select='$dst'/>
      </xsl:call-template>
    </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>


<xsl:template match="/">
  <xsl:apply-templates select="Figure" />
</xsl:template>

<xsl:template match="Figure">

  <input type="hidden" name="pdfpath" id="pdfpath">
    <xsl:attribute name="value">Catalog/PDF/<xsl:call-template name='replace'>
        <xsl:with-param name='str' select='./nm_pdf'/>
        <xsl:with-param name='src' select='" "'/>
        <xsl:with-param name='dst' select='"%20"'/>
      </xsl:call-template>
    </xsl:attribute>
  </input>
</xsl:template>

</xsl:stylesheet>

UPDATE3

我下载了一个 XML 编辑器,希望它可以调试我的 XML 和 XSL 文件并在浏览器之外执行它的转换。 XSL 文件看起来没问题;因此,我回去测试 XML 是否因某种原因而损坏。事实证明,XML 编辑器能够使用 XSL 文件转换 XML 文件。我可以说 XML 文件确实包含英语和东亚语言字符,编码为 UTF-8。但 IE 以及 XML 编辑器能够解析和转换它。那么,也许 Firefox 对 XML 文件的 UTF-8 编码有问题?

由于没有解决这个问题,我尝试了以下方法:

if (window.DOMParser)
{
  var serializer = new XMLSerializer();
  var XMLString = serializer.serializeToString(XML_Image);
  var parser = new DOMParser();
  var XML_Image_Again = parser.parseFromString(XMLString, "text/xml");
}

var Works = $.transform({async:false, xmlobj:XML_Image_Again, xsl:"xsl/ImageData.xsl"});
var AlsoWorks = $.transform({async:false, xmlstr:XMLString, xsl:"xsl/ImageData.xsl"});

Works = Works.replace(/&quot;/g,"\"");
Works = htmlfixed.replace(/(.gif).*?\"/g,"$1\"");

document.getElementById("DivContent").innerHTML = Works;

我所做的是将 XML 序列化为字符串。然后,我解析该字符串并尝试将其转换回 XML DOM 对象。由于某种原因,它仍然是一个字符串。因此,Works 采用字符串的值。 AlsoWorks* 也采用字符串的值,但这是期望的结果。奇怪的是,在我转换 XML 并将其传递给 Works 后,大多数引号都被搞乱了,并且一些其他数据被附加到我正在检索的图像的末尾 (.gif) 。因为 Works 是一个字符串,所以我无法使用appendChild 方法将其附加到DOM 树。我别无选择,只能使用innerHTML,我就这么做了。

所有这些时间和精力都是因为我正在处理的项目是基于 XML 和 XSL 文件。

我发现这个博客还记录了 FireFox 和 XSLT/XML/XSL 的困难:

http://ajaxandxml。 blogspot.com/search/label/Firefox

现在可以使用了,但我仍然摸不着头脑。一开始,我提到它在 IE 中运行得很好。而且,也许更重要的是,当我第一次将内容附加到 div 时(这是在页面初始化时),它可以在 FireFox 和 IE 中工作。只是在随后的几次我将内容附加到 div 时,FireFox 才不配合(Firebug 没有多大帮助,也不报告错误,与 IE 的 Web devleoper 工具栏不同)。在初始化时,我什至没有使用 jquery,只是使用本机 DOM。然而,当我使用 jquery 转换插件中的示例 XML 和 XSL 文件对时,它们工作得很好。只有当我同时使用 XML 和 XSL 文件时,它才会发出抱怨(同样,不是在页面首次加载时)。奇怪的是它不会转换 XML 对象,但在我序列化它之后,转换工作正常。

问题太多了。我说它可能是 FireFox 而不是 XML 或 XSL,因为如果 XML 和 XSL 文件有错误,那么当页面加载时转换应该会失败,但事实并非如此。

我确实很想知道为什么将对象附加到 div 不起作用,但将对象序列化为字符串并将其设置为innerHTML 属性,在转换后,以出色的方式传递。

UPDATE4

在我的 XSL 文件中,我将前两个模板放在单独的 XSL 文件中,并使用 xsl:import 功能。这又打破了。因此,FireFox 和 jquery 转换插件对 xsl:import 功能的响应不佳(IE 没有问题)。我尝试使用传输插件中的示例 XML 和 XSL 文件,该示例指定如何使用 xsl:import,但在 Firefox 中失败。

UPDATE5

我重构了代码,使其不使用 jquery,以调查 xsl:import 是否会失败。

// Test for Firefox only, purposely not including IE code
function TransformNodeTest(xmlobj, xslpath)
{
  var xslobj = LoadXSML(xslpath);
  var xsltProcessor = new XSLTProcessor();
  xsltProcessor.importStylesheet(xslobj);
  return(xsltProcessor.transformToFragment(xmlobj, document));
}
function LoadXSML(xslpath)
{
  var xhttp=new XMLHttpRequest();
  xhttp.open("GET",xslpath,false);
  xhttp.setRequestHeader("Pragma", "no-cache");
  xhttp.send();
  return xhttp.responseXML;
}

// ImageData.xsl contains xsl:import statement
// XML_Image is an XML obj
var FireFoxHTML = TransformNodeTest(XML_Image, "xsl/ImageData.xsl");

效果很好。

用 XML/XSL 内容替换 div 中的 XML/XSL 内容的结论 --

jquery 转换插件::

IE: 工作正常; xsl 文件中的 xsl:import 功能没有问题。

FireFox:出于某些未知原因(对我来说)不喜欢 xsl:import 功能。在出现更好的解决方案之前,我的权宜之计是将所有 XSL 语句复制/粘贴到一个文件中,而不是使用 xsl:import。此外,还需要序列化 ​​XML 对象,并且可以选择将其解析回 XML 对象以进行转换。为什么序列化可以修复它?我不知道。

XML DOM::

IE:工作正常; xsl 文件中的 xsl:import 功能没有问题。

FireFox:xsl:import 功能没有问题。需要序列化 ​​XML 对象,并且可以选择将其解析回 XML 对象以进行转换。为什么序列化可以修复它?我不知道。

重申一下,当页面最初加载时,XSLT 会在 div 上进行,并且在 FF 和 IE 中运行良好。只有在随后的时间里它才会在 FF 中失败(但在 IE 中不会)。

For the record, I am using Windows XP SP3, running FireFox 5 and IE 8.

I am working on a project that is using code from the stone ages, trying to refactor it, modernize it. It only worked on IE and involves heavy use of XML and XSLT.

When the page loads, content is dynamically placed inside a div using XSLT and XML preprocessing. This content consists of an img, map, and input tag, which is retrieved from an XSL file. That works fine in both Firefox and Internet Explorer; it loads fine and the image displays correctly, with the proper mappings, utilizing usemap attribute on the img.

There is a select box that allows the user to load a different image -- this is where I'm having issues. When the user makes a selection in the select box, it mirrors the steps when the page first loaded: XSLT, via an XML object and an XML file. Essentially, the contents of the div is reloaded.

This works well in Internet Explorer (IE); however, FireFox is is not transforming at all.

I found a jquery transform plugin and here is the line of code I am using:

function TransformXML()
{
  var html = null;
  var XML_Image = null;
  // Load XML document into XML_Image and do manipulation on it before transformation
  // ...
  // Further down in the function..

  if (document.implementation && document.implementation.createDocument)
  {
    html = $.transform({async:false, xmlobj:XML_Image, xsl:"xsl/ImageData.xsl"});
    document.getElementById("DivContent").appendChild(html);
  }
  else
  {
    html = $.transform({async:false, xmlobj:XML_Image, xsl:"xsl/ImageData.xsl"});
    document.getElementById("DivContent").innerHTML = html;
  }
}

As I said, IE works fine. Unfortunately, the html variable value is blank (FireBug reports ""). What could be the issue???

The XSL file does use XSL:import, but the jquery transform plugin worked fine for IE; I don't know if FireFox doesn't like it, though (FireBug is awful at debugging XSLT).

Thank you in advance for any help!

UPDATE

I have determined that it is something with the XSL file. I tried using a sample XML and XSL file from the jquery transform plugin and it worked. Then, I tried using my XML object, XML_Image, and the sample XSL file and it worked, too. Finally, I tried using a sample XML file and my XSL file, ImageData.xsl, and it did not work. I am not sure what is wrong with the XSL file, however.

UPDATE2

Well, I think it is something with the XSL file. Here it is:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>

  <xsl:template name="chgBR">

    <xsl:param name="str"/>
    <xsl:choose>
      <xsl:when test='$str = ""'>
        <br/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="$str"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

<xsl:template name="replace">
  <xsl:param name="str"/>
  <xsl:param name="src"/>
  <xsl:param name="dst"/>
  <xsl:if test='$str != ""'>
    <xsl:choose>
    <xsl:when test='substring-before( $str, $src ) = "" '>
      <xsl:value-of select='$str'/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select='substring-before( $str, $src )'/>
    <xsl:choose>
      <xsl:when test='$dst = "<br/>"'>
        <xsl:element name="br"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select='$dst'/>
      </xsl:otherwise>
      </xsl:choose>
      <xsl:call-template name='replace'>
        <xsl:with-param name='str' select='substring-after( $str,$src )'/>
        <xsl:with-param name='src' select='$src'/>
        <xsl:with-param name='dst' select='$dst'/>
      </xsl:call-template>
    </xsl:otherwise>
    </xsl:choose>
  </xsl:if>
</xsl:template>


<xsl:template match="/">
  <xsl:apply-templates select="Figure" />
</xsl:template>

<xsl:template match="Figure">

  <input type="hidden" name="pdfpath" id="pdfpath">
    <xsl:attribute name="value">Catalog/PDF/<xsl:call-template name='replace'>
        <xsl:with-param name='str' select='./nm_pdf'/>
        <xsl:with-param name='src' select='" "'/>
        <xsl:with-param name='dst' select='"%20"'/>
      </xsl:call-template>
    </xsl:attribute>
  </input>
</xsl:template>

</xsl:stylesheet>

UPDATE3

I downloaded an XML editor, in hope it could debug my XML and XSL files and execute a transformation of it, outside of the browser. The XSL file appeared to be okay; so, I went back to testing if the XML was, somehow, corrupt. As it turns out, the XML editor was able to transform the XML file using the XSL file. I can say the XML file does contain english and eastern asian language characters, encoded as UTF-8. But IE was able to parse and transform it, as well as the XML Editor. So, perhaps Firefox has a problem with the XML Files' UTF-8 encoding?

Having no answer to this problem, I tried this:

if (window.DOMParser)
{
  var serializer = new XMLSerializer();
  var XMLString = serializer.serializeToString(XML_Image);
  var parser = new DOMParser();
  var XML_Image_Again = parser.parseFromString(XMLString, "text/xml");
}

var Works = $.transform({async:false, xmlobj:XML_Image_Again, xsl:"xsl/ImageData.xsl"});
var AlsoWorks = $.transform({async:false, xmlstr:XMLString, xsl:"xsl/ImageData.xsl"});

Works = Works.replace(/"/g,"\"");
Works = htmlfixed.replace(/(.gif).*?\"/g,"$1\"");

document.getElementById("DivContent").innerHTML = Works;

What I did was serialize the XML to a string. Then, I parsed the string and attempted to convert it back to a XML DOM object. For some reason, it stayed a string. As a result, Works takes the value of a string. AlsoWorks* takes the value of a string, as well, but this is the desired result. What's odd is after I transformed the XML and passed it to Works, most of the quotation symbols got messed up and some some other data was appended to the end of the image I'm retrieving (.gif). Because Works is a string, I could not use the appendChild method to attach it to the DOM tree. I was left with no choice but to use innerHTML, which I did.

All this time and energy because the project I'm working with is entrenched with XML and XSL files.

I found that this blog also documents difficulties with FireFox and XSLT/XML/XSL:

http://ajaxandxml.blogspot.com/search/label/Firefox

It works now, but I'm still scratching my head. In the beginning, I mentioned it works in IE just fine. And, perhaps more importantly, it works in BOTH FireFox and IE the first time I attach content to the div, which is upon initialization of the page. It's only on subsequent times I am attaching content to the div that FireFox doesn't cooperate (and Firebug doesn't help much, nor does it report errors, unlike IE's web devleoper toolbar). And upon initialization, I'm not even using jquery, just native DOM. And, yet, when I used sample XML and XSL file pairs from the jquery transform plugi, those worked fine. It's only when I use both my XML and XSL files together that it complains (again, not when the page first loads). The strange thing is it wouldn't transform the XML object, but after I serialized it, the transformation worked fine.

Too many questions. I say it's probably FireFox and not the XML or XSL, because if the XML and XSL files were at fault, then the transformation should fail when the page loads and, yet, it does not.

I sure as heck would love to know why appending the object to the div didn't work but serializing the object to a string and setting it to the innerHTML property, after transformation, passed with flying colors.

UPDATE4

In my XSL file, I placed the first two templates in a separate XSL file and am using the xsl:import feature, instead. This broke it again. So, FireFox and jquery transform plugin do not respond well to the xsl:import feature (IE has no issue with it). I tried using the sample XML and XSL files from the transport plugin, the example which specifies how to use xsl:import, and it failed in firefox.

UPDATE5

I refactored the code, such that it does not use jquery, to investigate if xsl:import will fail.

// Test for Firefox only, purposely not including IE code
function TransformNodeTest(xmlobj, xslpath)
{
  var xslobj = LoadXSML(xslpath);
  var xsltProcessor = new XSLTProcessor();
  xsltProcessor.importStylesheet(xslobj);
  return(xsltProcessor.transformToFragment(xmlobj, document));
}
function LoadXSML(xslpath)
{
  var xhttp=new XMLHttpRequest();
  xhttp.open("GET",xslpath,false);
  xhttp.setRequestHeader("Pragma", "no-cache");
  xhttp.send();
  return xhttp.responseXML;
}

// ImageData.xsl contains xsl:import statement
// XML_Image is an XML obj
var FireFoxHTML = TransformNodeTest(XML_Image, "xsl/ImageData.xsl");

It worked fine.

Conclusions for replacing XML/XSL content in div with XML/XSL content--

jquery transform plugin::

IE: Works fine; no issues with xsl:import feature in xsl file.

FireFox: Does not like xsl:import feature for some unknown reason (to me). My stopgap, until a better solution comes along, is copy/paste all XSL statements into one file and not use xsl:import. Also, need to serialize the XML obj and, optionally, parse it back to an XML object to transform. Why does serializing fix it? I do not know.

XML DOM::

IE: Works fine; no issues with xsl:import feature in xsl file.

FireFox: No issue with xsl:import feature. Need to serialize the XML obj and, optionally, parse it back to an XML object to transform. Why does serializing fix it? I do not know.

To reiterate, when the page loads initially, XSLT is conducted on the div and it works fine in FF and IE. It's only on subsequent times does it fail in FF (but not IE).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

油饼 2024-12-02 16:14:00

我的解决方案是放弃 XSLT 并用 JavaScript 编写 HTML 并将其附加到 DOM。如果这是对页面的一个 XSLT 调用,那么我想我会进一步尝试实现跨浏览器兼容性。我相信由于一些时间和加载问题,它部分失败了。我稍后可能会重新访问并更新此空间。

My solution was abandoning XSLT and writing HTML in JavaScript and attaching it to the DOM. If it was one XSLT call for a page, then I suppose I would've made further attempts to achieve cross-browser compatibility. And I believe it was partially failing due to some timing and loading issues. I may revisit it later and update this space.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文