как избежать XML-объектов в javascript?
в JavaScript (на стороне сервера nodejs) я пишу программу, которая генерирует xml в качестве вывода.
Я строю xml путем объединения строки:
str += '<' + key + '>';
str += value;
str += '</' + key + '>';
проблема в том, что если value
содержит символы, такие как '&'
,'>'
или '<'
?
Каков лучший способ избежать этих персонажей?
или есть ли библиотека javascript, вокруг которой можно избежать XML-объектов?
8 ответов:
HTML кодировка просто заменяет
&
,"
,'
,<
и>
символы с их эквивалентами сущностей. Порядок имеет значение, если вы не замените&
символы во-первых, вы будете дважды кодировать некоторые из объектов:if (!String.prototype.encodeHTML) { String.prototype.encodeHTML = function () { return this.replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); }; }
как отметил @Johan B. W. de Vries, у этого будут проблемы с именами тегов, я хотел бы уточнить, что я сделал предположение, что это используется для
value
тольконаоборот, если вы хотите декодировать HTML-объекты1, убедитесь, что вы расшифруйте
&
до&
после всего остального, так что вы не дважды декодировать любые объекты:if (!String.prototype.decodeHTML) { String.prototype.decodeHTML = function () { return this.replace(/'/g, "'") .replace(/"/g, '"') .replace(/>/g, '>') .replace(/</g, '<') .replace(/&/g, '&'); }; }
1 только основы, не включая
©
до©
или другие подобные вещи
что касается библиотек. подчеркивания.js (или Лодашь если вы предпочитаете) обеспечивает
_.escape
способ для выполнения этой функции.
Это может быть немного более эффективным с тем же результатом:
function escapeXml(unsafe) { return unsafe.replace(/[<>&'"]/g, function (c) { switch (c) { case '<': return '<'; case '>': return '>'; case '&': return '&'; case '\'': return '''; case '"': return '"'; } }); }
Если у вас есть jQuery, вот простое решение:
String.prototype.htmlEscape = function() { return $('<div/>').text(this.toString()).html(); };
используйте его так:
"<foo&bar>".htmlEscape();
->"<foo&bar>"
вы можете использовать следующий метод. Я добавил Это в прототип для более легкого доступа. Я также использовал отрицательный взгляд вперед, поэтому он не испортит вещи, если вы вызовете метод дважды или более.
использование:
var original = "Hi&there"; var escaped = original.EncodeXMLEscapeChars(); //Hi&there
декодирование автоматически обрабатывается в XML-парсере.
способ :
//String Extenstion to format string for xml content. //Replces xml escape chracters to their equivalent html notation. String.prototype.EncodeXMLEscapeChars = function () { var OutPut = this; if ($.trim(OutPut) != "") { OutPut = OutPut.replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'"); OutPut = OutPut.replace(/&(?!(amp;)|(lt;)|(gt;)|(quot;)|(#39;)|(apos;))/g, "&"); OutPut = OutPut.replace(/([^\])((\\)*)\(?![\/{])/g, "\\"); //replaces odd backslash(\) with even. } else { OutPut = ""; } return OutPut; };
Я первоначально использовал принятый ответ в производственном коде и обнаружил, что он был на самом деле очень медленным при интенсивном использовании. Вот это много более быстрое решение (работает более чем в два раза быстрее):
var escapeXml = (function() { var doc = document.implementation.createDocument("", "", null) var el = doc.createElement("temp"); el.textContent = "temp"; el = el.firstChild; var ser = new XMLSerializer(); return function(text) { el.nodeValue = text; return ser.serializeToString(el); }; })(); console.log(escapeXml("<>&")); //<>&
может быть, вы можете попробовать это,
function encodeXML(s) { const dom = document.createElement('div') dom.textContent = s return dom.innerHTML }
технически,&, не являются допустимыми символами имени сущности XML. Если вы не можете доверять ключевой переменной, вы должны фильтровать их.
Если вы хотите, чтобы они экранировались как HTML-объекты, вы можете использовать что-то вроде http://www.strictly-software.com/htmlencode .