Error parsing XHTML: The content of elements must consist of well-formed character data or markup
Asked Answered
O

5

50

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?

Outdo answered 2/12, 2010 at 18:35 Comment(0)
F
111

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 were 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. Additional advantage is that this gives the browser the opportunity to cache the JS file so that average response size is smaller.

See also:

Fissile answered 2/12, 2010 at 19:10 Comment(26)
The javascript doesn't run when I use the <![CDATA[ block or using an external js file. I shortened the code for myScript() to window.location='fileServlet?param=1';, and this only runs if I put it inline with onclick or in <script type="text/javascript"></script>Outdo
How did you invoke it? By onclick="myScript()" I suppose?Fissile
While wrapping in <![CDATA[ did you ensure that you followed the instructions in the link as in my answer? There has got to be a ]]> at end. When using an external script, did you ensure that the .js file didn't contain the <script>, but just a function myScript() {} ?Fissile
yes, I used a <![CDATA[ and ]]> block and had a global.js with only function myScript() {}Outdo
I spotted some minor errors in your JS function (among others, you omitted a ', but that should have resulted in a JS error, did you see it in JS console?) and the logic could be more simplified. I updated the answer with an example.Fissile
Dang it, I was typing in the same answer. Including your javascript in a separate file will definitely solve this issue, and is generally a best practice.Devine
@Naganalf: You started typing 44 minutes ago? :)Fissile
Started yes, then something came up here to distract me. :PDevine
Thanks for the updated code. But again, running it in global.js like the example, even if I shorten it to window.location='fileServlet?param=1'; it doesn't seem to run.Outdo
@Naganalf: Haha ok. Sorry about that :P Next time better.Fissile
It doesn't get invoked at all? Do you see any JS errors in the JS console? Is the global.js reachable anyway? (i.e. its URL is correct and so on). Web developer tools like Firebug and Web Developer Toolbar for Firefox may give lot of new insights.Fissile
Ok, after restarting server and refreshing page, clearing browser cache a couple times I got the global.js running. But only this part if(checked) window.location='fileServlet?param=1'; As soon as I put in the line var box = document.getElementbyId('myForm:box'); it doesn't download the file, even when the param is currently hard-coded. I will look into using Firebug.Outdo
Only by just putting this line? Interesting, this would suggest that calling document threw an exception. Anyway, is the element ID correct as per the generated HTML?Fissile
yup, my listbox id is box and my form id is myForm It was able to get the checkbox element.Outdo
Press Ctrl+Shift+J to get the standard JS error console in Firefox. It might contain useful debug information.Fissile
ah I was using getElementbyId instead of getElementById Now it triggers the download.Outdo
Thanks for tip on using external js and error console and fixing the logic too.Outdo
Ahh, my own typo. Sorry about that. Just typed straight from head :) But is it now working?Fissile
It's only passing one param so far instead of the whole chain. I'm using getParameterValues. I'll get back to you.Outdo
Hmm, I shouldn't be doing length - 1, that's the options available in list box not the total of selected. I'll get back to you.Outdo
This should actually not harm. Put an alert(paramstring) or with Firebug, console.log(paramstring) before window.location to see if it's correct.Fissile
but the paramstring before was putting &amp; at the end because it wasn't at length - 1 even when I was already at the end of all the selections. I updated the code now, please see updated question. thanks.Outdo
I updated the answer, but I see that you used &amp; in JS. This is unnecessary. The &amp; is only necessary when writing in a XML file. The XML parser will then turn it into a &.Fissile
Ignore the code that I updated, yours is outputting the correct paramstring and I'm getting the correct String array with getParameterValues. Thanks.Outdo
I am using left shift operator in my code ( << ) for this it is giving me that Error parsing XHTML: The content of elements must consist of well-formed character data or markupClemmie
Wow, how in a earth, you have found out this.Isbella
A
22

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!

Autotransformer answered 19/10, 2011 at 19:16 Comment(1)
This means that you're serving HTML as application/xhtml+xml (see also the CDATA link in my answer developer.mozilla.org/en/Writing_JavaScript_for_XHTML). Serving HTML as such is considered harmful (especially in MSIE browser).Fissile
H
6

Sometimes you will need this :

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

and not only this :

 <![CDATA[
 ]]>
Hodometer answered 22/5, 2014 at 8:7 Comment(0)
N
1

I had a git conflict left in my workspace.xml i.e.

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

which caused the unknown tag error. It is a bit annoying that it doesn’t name the file.

Nipper answered 9/5, 2019 at 22:28 Comment(0)
B
-2

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>
...
Bedouin answered 2/11, 2015 at 17:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.