Error parsing XHTML: The content of elements must

2019-01-01 03:54发布

问题:

As an extension of this question, I\'m trying to insert Javascript to a <h:commandButton />\'s onclick property as action is already rendering an ajax table.

What I want to do: Get the selected items in a list box and turn them into parameters to be used in a JSF FileServlet. i.e. para2=value1&param=value2&param=value3

Here\'s what I have:

<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>  

What I get when page is loaded: javax.servlet.ServletException: Error Parsing /page.xhtml: Error Traced[line:15] The content of elements must consist of well-formed character data or markup.

What doesn\'t trigger exception:

<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> 

As soon as I add in for (var i = 0; i < length; i++) or even for (var i = 0; i < 10; i++) the page wouldn\'t load. Why does it not like the for loop?

回答1:

Facelets is a XML based view technology which uses XHTML+XML to generate HTML output. XML has five special characters which has special treatment by the XML parser:

  • < the start of a tag.
  • > the end of a tag.
  • \" the start and end of an attribute value.
  • \' the alternative start and end of an attribute value.
  • & the start of an entity (which ends with ;).

In case of <, the XML parser is implicitly looking for the tag name and the end tag >. However, in your particular case, you was using < as a JavaScript operator, not as an XML entity. This totally explains the XML parsing error you got:

The content of elements must consist of well-formed character data or markup.

In essence, you\'re writing JavaScript code in the wrong place, a XML document instead of a JS file, so you should be escaping all XML special characters accordingly. The < must be escaped as &lt;.

So, essentially, the

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

must become

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

to make it XML-valid.

However, this makes the JavaScript code harder to read and maintain. As stated in Mozilla Developer Network\'s excellent document Writing JavaScript for XHTML, you should be placing the JavaScript code in a character data (CDATA) block. Thus, in JSF terms, that would be:

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

The XML parser will interpret the block\'s contents as \"plain vanilla\" character data and not as XML and hence interpret the XML special characters \"as-is\".

But, much better is to just put the JS code in its own JS file which you include by <script src>, or in JSF terms, the <h:outputScript>.

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

This way you don\'t need to worry about XML-special characters in your JS code.

See also:

  • The entity name must immediately follow the '&' in the entity reference
  • Is it possible to use JSF+Facelets with HTML 4/5?
  • How to reference CSS / JS / image resource in Facelets template?
  • Writing JavaScript for XHTML


回答2:

I ran across this post today as I was running into the same issue and had the same problem of the javascript not running with the CDATA tags listed above. I corrected the CDATA tags to look like:

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

your javascript code here

//]]>
</script>

Then everything worked perfectly!



回答3:

Sometimes you will need this :

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

and not only this :

 <![CDATA[
 ]]>


回答4:

I solved this converting the JSP from XHTML to HTML, doing this in the begining:

<%@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>
...