Does anybody know how to embed some arbitrary xml within an xhtml document, and then make the xml available to javascript code as pure text? I have developed a library originally intended to process xml data read in using Ajax, but in some circumstances it is inconvenient to have to seperate the data from the html document.
I know it is possible to replace ‘<’ and ‘>’ with < and >, but this is cumbersome with more than trivial amounts of xml, plus it requires more processing in the js code.
I had thought I could just encode the xml as CDATA, e.g.
The whole point of a CDATA section is that it won’t be parsed by the XHTML parser (in this case, the browser.) So the data won’t be available via the DOM API.
If you want to get this XML in Javascript, you’ll either need to encode it as HTML entities (a terrible idea) or fire off an asynchronous request to get it directly from the server (a much better idea.)
It’s there, you’re just not looking in the right place. Your “myxml.firstChild” is just getting the Text object containing the whitespace between the closing > of the DIV and the opening < of the CDATA. The myxml DIV should have three children: a Text object, a CDATASection object, and another Text object. You either need to iterate over all of these to accumulate the value, or just call “.textContent” to get the value.
Here (NB: only tested on Firefox; no doubt IE uses some other field name. Also, the form submission chokes on SCRIPT tag pairs, so de-leet-ify the closing tag to make it work):
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US">
<head><title>XML CDATA</title>
<script type="text/javascript"><![CDATA[
function getxml1() {
document.getElementById("ta1").value = document.getElementById("myxml").textContent
}
function getxml2() {
var ta2 = document.getElementById("ta2")
var ta3 = document.getElementById("ta3")
var xmlchildren = document.getElementById("myxml").childNodes
ta2.value = ta3.value = ''
for ( var n = 0; n < xmlchildren.length; ++n ) {
ta2.value += xmlchildren[n] + ': ' + xmlchildren[n].nodeValue
ta3.value += xmlchildren[n] + ' '
}
ta2.value += '[end]'
}
]]></5CR1PT>
</head>
<body onload="getxml1();getxml2();">
<div id="myxml">
<![CDATA[
<foo>
<bar>some text</bar>
</foo>
]]>
</div>
<table style="text-align: right;">
<tr><td>myxml.textContent</td><td><textarea cols="60" rows="6" id="ta1"/></td></tr>
<tr><td>myxml.childNodes</td><td><textarea cols="60" rows="1" id="ta3"/></td></tr>
<tr><td>myxml.childNodes values</td><td><textarea cols="60" rows="6" id="ta2"/></td></tr>
</table>
</body></html>
From what I can see now FF and IE8 do things completely differently (big shock - not) and, despite being in CDATA, IE8 tries to parse the contents anyway - chopping the contents into a mixture of Text node, undefinedHtml nodes plus a few more for good measure - nightmare.
I did however discover a rather obvious and simple solution. Using my previous example I could just code:
var cdata = document.getElementById("myxml").innerHTML;
I can then strip off the <div> and <![CDATA[ stuff in code. Obvious really. :smack::smack::smack:
Seems to work in FF, IE8 and Google Chrome - the only browsers I have handy right now but I can’t see why it shouldn’t work in others just as well.