我正在使用XML DOM技术在JavaScript中构建下拉菜单。创建<option>
节点后,我附加了应该为该选项显示的文本。我面临的问题是,当文本包含字符实体引用(CER)时,例如₂
&amp; CER的字符被转义为&
,因此当菜单输出到页面进行显示时,CER而不是字符会显示在选择菜单中。我尝试了以下两种方法:
optionNode.appendChild(xmlDoc.createTextNode(label));
和
optionNode.textContent = label;
并且都给出相同的结果。在将XML文档输出到文本后,我可以通过使用&
全局替换&
来解决此问题:
var xml = (new XMLSerializer()).serializeToString(xmlDoc);
return xml.replace(/&/g, '&');
但我确信必须有办法避免首先逃避。有什么建议吗?
答案 0 :(得分:0)
您可以使用createCDATASection()
代替createTextNode()
var docu = new DOMParser().parseFromString('<xml></xml>', "application/xml")
var cdata = docu.createCDATASection('Some <CDATA> data & then some');
docu.getElementsByTagName('xml')[0].appendChild(cdata);
alert(new XMLSerializer().serializeToString(docu));
// Displays: <xml><![CDATA[Some <CDATA> data & then some]]></xml>
答案 1 :(得分:0)
我找到了解决方案。在创建包含label
的节点之前,我将label
中的所有字符实体引用转换为Unicode字符。然后,当我将xml作为String输出时,我将所有Unicode字符转换回字符实体引用。代码改编自我发现elsewhere on Stack Overflow的代码。
function cerToUnicode(str) {
"use strict";
var entity_table = {
'"': String.fromCharCode(34), // Quotation mark. Not required
'&': String.fromCharCode(38), // Ampersand
'<': String.fromCharCode(60), // Less-than sign
'>': String.fromCharCode(62), // Greater-than sign
' ': String.fromCharCode(160), // Non-breaking space
'¡': String.fromCharCode(161), // Inverted exclamation mark
... // other named CERs
};
str = str.replace(/&#(\d+);/g,
function (matched, capture1) {
return (capture1 == '38' ? '&' : String.fromCharCode(capture1));
});
str = str.replace(/&[^;]*;/g,
function (matched) {
return entity_table[matched];
});
return str;
} // cerToUnicode()
function unicodeToCER(str) {
return str.replace(/./gm, function(s) {
var code = s.charCodeAt(0);
return (code < 128 ? s : "&#" + code + ";");
});
} // unicodeToCER()