Я пытаюсь найти кросс-браузерный способ сериализации SVG-документа, содержащего CDATA.
Мой код хорошо работает в Chrome и Firefox, но в Internet Explorer CDATA сериализуется как текст, а не раздел CDATA. Вот моя реализация:
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var xml = new DOMParser().parseFromString('<xml></xml>', "application/xml");
var cdata = xml.createCDATASection('Some data & some more');
svg.appendChild(cdata);
log("Node Type: " + cdata.nodeName)
log("SVG: " + new XMLSerializer().serializeToString(svg));
// Utility function for output
function log(s) {
var output = document.getElementById('output');
if (output) {
output.innerHTML += new Option(s).innerHTML + '<br>';
} else {
console.log(s);
}
}
<div id="output"></div>
В Chrome и Firefox вывод XMLSerializer выглядит так, как ожидалось: <svg xmlns="http://www.w3.org/2000/svg"><![CDATA[Some data & some more]]></svg>
Но в Internet Explorer CDATA записывается как простой текстовый узел: <svg xmlns="http://www.w3.org/2000/svg">Some data & some more</svg>
Я попробовал добавить данные раздела CDATA в "<! [CDATA [" и "]]>", но это не работает, потому что он будет экранирован. Есть ли что-нибудь, что я могу сделать, чтобы Internet Explorer правильно написал раздел CDATA?
Примечание. Фрагмент не работает в Internet Explorer, если он встроен в Stackoverflow, но он работает как отдельный файл.
Я придумал хакерское решение, которое не очень приятно, но оно работает.
Перед сериализацией данные cdata
окружены маркером начала и конца (я использую __CDATA
и CDATA__
а после сериализации регулярное выражение используется для замены маркеров (и дополнительных открывающих и торцевых тегов CDATA) с помощью открывающих и заканчивающих тегов CDATA.
Необязательно, чтобы обнюхивание браузера могло использоваться, чтобы определить, нужен ли этот взлом вообще.
Вот модифицированный пример:
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var xml = new DOMParser().parseFromString('<xml></xml>', "application/xml");
var cdata = xml.createCDATASection('Some data & some more');
// Add markers
cdata.data = "__CDATA" + cdata.data + "CDATA__";
svg.appendChild(cdata);
var svgStr = new XMLSerializer().serializeToString(svg);
// Replace markers (and already existing CDATA start and end tags)
svgStr = svgStr.replace(/(?:<\!\[CDATA\[)?__CDATA(.*?)CDATA__(?:\]\]>)?/g, '<![CDATA[$1]]>');
log("SVG: " + svgStr);
// Utility function for output
function log(s) {
var output = document.getElementById('output');
if (output) {
output.innerHTML += new Option(s).innerHTML + '<br>';
} else {
console.log(s);
}
}
<div id="output"></div>
new Option(s).innerHTML
выполняет экранирование для вывода, и если я пишу в консоль, вывод выглядит так же. Я почти уверен, что браузер ничего не проглотит.