I\'m having trouble with special characters that exist in an xml node attribute. To combat this, I\'m trying to render the attributes as child nodes and, where necessary, using
I had the same issue. i was trying to append CDATA to xml nodes, so i thought its as easy as adding like so:
valueNode[0].text = "<![CDATA["+ tmpVal +"]]>";
//valueNode[0] represents "<value></value>"
This does not work because the whole thing will get interpreted as text therefore <(less than) and > (great than) will be replaced automatically.
what you need to do is use createCDATASection by doing the following:
var tmpCdata = $xmlDoc[0].createCDATASection(escape("muzi test 002"));
//i'm also escaping special charactures as well
valueNode[0].appendChild(tmpCdata);
results will be:
<value><![CDATA[muzi%20test%20002]]></value>
Brettz9 (in previous answer) explains how to do this but quite complex, therefore i just wanted to add my solution which is much simpler.
thanks,
Not sure of browser support for document.implementation.createDocument or createCDataSection, but this works in Mozilla at least:
<script>
// Define some helpers (not available IE < 9)
function parse (str) {
return new DOMParser().parseFromString(str, 'text/xml').documentElement;
}
function ser (dom) {
return new XMLSerializer().serializeToString(dom);
}
// Simulate your XML retrieval
var row = '<row pSiteID="4" pSiteTile="Test Site Name " pSiteURL="http://www.cnn.com" ID="1" Description="<div>blah blah blah since June 2007.&nbsp; T<br>&nbsp;<br>blah blah blah blah&nbsp; </div>" CreatedDate="2010-09-20 14:46:18" Comments="Comments example. " />';
// Hack to convert source to well-formed XML, or otherwise you can't use DOM methods on it which
// depend on well-formed XML
row = row.replace(/(=\s*")([\s\S]*?)(")/g, function (n0, n1, n2, n3) {
return n1+ // Add back equal sign and opening quote
n2.replace(/</g, '<'). // Create well-formed XML by avoiding less-than signs inside attributes
replace(/&nbsp;/g, '&#160;')+ // HTML entities (except for gt, lt, amp, quot) must be either converted to numeric character references or your XML must define the same entities
n3; // Add back closing quote
});
// Simulate your retrieval of DOM attributes, though in this context, we're just making attributes into a global
this.attributes = parse(row).attributes;
// Simulate your creation of an XML document
var newXMLData = document.implementation.createDocument(null, 'Site', null);
// Modify your code to avoid jQuery dependency for easier testing and to
// avoid confusion (error?) of having two variables, newXMLData and newXMLDataNode
for (var ctr =0;ctr< this.attributes.length;ctr++){ // iterate over the attributes
if (this.attributes[ctr].name =="Description") { // if the attribute name is "Description" add a CDATA section
var thisNodeName = this.attributes[ctr].name;
var str = "<"+thisNodeName +"></"+ thisNodeName +">";
var node = parse(str);
var cdata = newXMLData.createCDATASection(this.attributes[ctr].textContent);
node.appendChild(cdata);
newXMLData.documentElement.appendChild(node);
}
else {
// It's not "Description" so just append the new node.
var str= "<"+ this.attributes[ctr].name +">" + this.attributes[ctr].textContent + "</"+ this.attributes[ctr].name +">";
newXMLData.documentElement.appendChild(parse(str));
}
}
// Prove its working (though you may wish to use toUpperCase() if you need the element names upper-cased);
// if you need CDATA for Comments, you can follow the pattern above to add support for that too
alert(ser(newXMLData));
</script>