document.createCDATASection
должен сделать это, но реальный ответ на ваш вопрос заключается в том, что хотя HTML 5 имеет секции CDATA кросс-браузерная поддержка для них довольно нечеткая.
EDIT
Разделы CDATA просто не входят в определение HTML 4, поэтому большинство браузеров их не распознают.
Но для этого не требуется полный анализатор DOM. Вот простое лексическое решение, которое решит проблему.
function htmlWithCDATASectionsToHtmlWithout(html) {
var ATTRS = "(?:[^>\"\']|\"[^\"]*\"|\'[^\']*\')*",
// names of tags with RCDATA or CDATA content.
SCRIPT = "[sS][cC][rR][iI][pP][tT]",
STYLE = "[sS][tT][yY][lL][eE]",
TEXTAREA = "[tT][eE][xX][tT][aA][rR][eE][aA]",
TITLE = "[tT][iI][tT][lL][eE]",
XMP = "[xX][mM][pP]",
SPECIAL_TAG_NAME = [SCRIPT, STYLE, TEXTAREA, TITLE, XMP].join("|"),
ANY = "[\\s\\S]*?",
AMP = /&/g,
LT = /</g,
GT = />/g;
return html.replace(new RegExp(
// Entities and text
"[^<]+" +
// Comment
"|<!--"+ANY+"-->" +
// Regular tag
"|<\/?(?!"+SPECIAL_TAG_NAME+")[a-zA-Z]"+ATTRS+">" +
// Special tags
"|<\/?"+SCRIPT +"\\b"+ATTRS+">"+ANY+"<\/"+SCRIPT +"\\s*>" +
"|<\/?"+STYLE +"\\b"+ATTRS+">"+ANY+"<\/"+STYLE +"\\s*>" +
"|<\/?"+TEXTAREA+"\\b"+ATTRS+">"+ANY+"<\/"+TEXTAREA+"\\s*>" +
"|<\/?"+TITLE +"\\b"+ATTRS+">"+ANY+"<\/"+TITLE +"\\s*>" +
"|<\/?"+XMP +"\\b"+ATTRS+">"+ANY+"<\/"+XMP +"\\s*>" +
// CDATA section. Content in capturing group 1.
"|<!\\[CDATA\\[("+ANY+")\\]\\]>" +
// A loose less-than
"|<", "g"),
function (token, cdataContent) {
return "string" === typeof cdataContent
? cdataContent.replace(AMP, "&").replace(LT, "<")
.replace(GT, ">")
: token === "<"
? "<" // Normalize loose less-thans.
: token;
});
}
Учитывая
<b>foo</b><![CDATA[<i>bar</i>]]>
производит
<b>foo</b><i>bar</i>
и что-то, похожее на раздел CDATA внутри script
или другого специального тега или комментария, корректно не смешивается с ним:
<script>/*<![CDATA[*/foo=bar<baz&//]]></script><![CDATA[fish: <><]]>
становится
<script>/*<![CDATA[*/foo=bar<baz&//]]></script>fish: <><