解析 XHTML 时出错:元素的内容必须由格式正确的字符数据或标记组成

IT技术 javascript jsf jsf-2 xhtml facelets
2021-02-09 10:12:54

作为这个问题的扩展,我正在尝试将 Javascript 插入到 a<h:commandButton />onclick属性中,因为action它已经呈现了一个 ajax 表。

我想要做什么:在列表框中获取所选项目并将它们转换为要在 JSF 中使用的参数FileServletIEpara2=value1&param=value2&param=value3

这是我所拥有的:

<script type ="text/javascript">
function myScript() {
    var box = document.getElementbyId('myForm:box');
    var length = box.options.length;
    var paramstring = "";
    for (var i = 0; i < length; i++) {
        if (i != (length - 1) {
            if (box.options[i].selected) {
                paramstring = paramstring + "param=" + box.options[i].value + "&amp;";
            }
        } else {
            paramstring = paramstring + "param=" + box.options[i].value;
        }
    }
    if (document.getElementById('myForm:checkbox').checked) {
        window.location='fileServlet? + paramstring;
    }
}
</script>  

页面加载时我得到了什么: javax.servlet.ServletException: Error Parsing /page.xhtml: Error Traced[line:15] The content of elements must consist of well-formed character data or markup.

什么不会触发异常:

<script type ="text/javascript">
function myScript() {
    var box = document.getElementbyId('myForm:box');
    var length = box.options.length;
    var paramstring = "";

    if (document.getElementById('myForm:checkbox').checked) {
        window.location='fileServlet? + paramstring;
    }
}
</script> 

一旦我添加,for (var i = 0; i < length; i++)甚至for (var i = 0; i < 10; i++)页面都不会加载。为什么它不喜欢 for 循环?

5个回答

Facelets 是一种基于 XML 的视图技术,它使用 XHTML+XML 生成 HTML 输出。XML 有五个特殊字符,它们被 XML 解析器特殊处理:

  • < 标签的开始。
  • > 标签的结尾。
  • " 属性值的开始和结束。
  • ' 属性值的替代开始和结束。
  • &实体的开头(以 结尾;)。

在 的情况下<,XML 解析器隐式地寻找标记名称和结束标记>但是,在您的特定情况下,您使用的<是 JavaScript 运算符,而不是 XML 实体。这完全解释了您遇到的 XML 解析错误:

元素的内容必须由格式良好的字符数据或标记组成。

本质上,您在错误的位置编写了 JavaScript 代码,即 XML 文档而不是 JS 文件,因此您应该相应地转义所有 XML 特殊字符。<必须进行转义为&lt;

所以,本质上,

for (var i = 0; i < length; i++) {

必须成为

for (var i = 0; i &lt; length; i++) {

使其 XML 有效。

然而,这使得 JavaScript 代码更难阅读和维护。正如 Mozilla Developer Network 的优秀文档为 XHTML 编写 JavaScript 中所述,您应该将 JavaScript 代码放置在字符数据 (CDATA) 块中。因此,在 JSF 术语中,这将是:

<h:outputScript>
    <![CDATA[
        // ...
    ]]>
</h:outputScript>

XML 解析器将块的内容解释为“普通”字符数据而不是 XML,因此解释 XML 特殊字符“原样”。

但是,更好的是只是把自己的JS文件中的JS代码,您包括由<script src>,或者在JSF方面,<h:outputScript>

<h:outputScript name="functions.js" target="head" />

这样您就无需担心 JS 代码中的 XML 特殊字符。另一个好处是,这让浏览器有机会缓存​​ JS 文件,从而使平均响应大小更小。

也可以看看:

在包装时,<![CDATA[您是否确保按照我的回答中的链接中的说明进行操作?必须有一个]]>结尾。使用外部脚本时,您是否确保.js文件不包含<script>,而仅包含function myScript() {}
2021-03-13 10:12:54
是的,我使用了一个<![CDATA[and]]>块并且只有一个global.jswithfunction myScript() {}
2021-03-20 10:12:54
我在你的 JS 函数中发现了一些小错误(除其他外,你省略了 a ',但这应该会导致一个 JS 错误,你在 JS 控制台中看到了吗?)并且逻辑可以更简化。我用一个例子更新了答案。
2021-04-01 10:12:54
你是怎么调用的?通过onclick="myScript()"我想?
2021-04-08 10:12:54
当我使用<![CDATA[块或使用外部 js 文件时,javascript 不会运行我缩短了myScript()to的代码window.location='fileServlet?param=1';,这只有在我将它内联onclick放入时才会运行<script type="text/javascript"></script>
2021-04-09 10:12:54

我今天遇到了这篇文章,因为我遇到了同样的问题,并且 javascript 没有运行上面列出的 CDATA 标签。我更正了 CDATA 标签,看起来像:

<script type="text/javascript">
//<![CDATA[ 

your javascript code here

//]]>
</script>

然后一切正常!

这意味着您将 HTML 作为application/xhtml+xml(另请参阅我的回答developer.mozilla.org/en/Writing_JavaScript_for_XHTML 中的 CDATA 链接)。像这样提供 HTML 被认为是有害的(尤其是在 MSIE 浏览器中)。
2021-04-02 10:12:54

有时你会需要这个:

 /*<![CDATA[*/
 /*]]>*/

不仅如此:

 <![CDATA[
 ]]>

我的workspace.xml 中有一个git 冲突,即

<<<<———————HEAD

这导致了未知的标签错误。它没有命名文件有点烦人。

我解决了将 JSP 从 XHTML 转换为 HTML 的问题,一开始就这样做:

<%@page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
...