如何在JavaScript中转义xml实体?

在JavaScript(服务器端nodejs)我正在写一个程序,产生XML作为输出。

我通过串联string来构buildxml:

str += '<' + key + '>'; str += value; str += '</' + key + '>'; 

问题是:如果value包含'&''>''<'等字符? 逃避这些angular色的最好方法是什么?

或者是否有任何可以转义XML实体的JavaScript库?

HTML编码就是简单地用它们的实体等价物replace&"'<>字符。如果你不先replace字符,那么你会对一些实体进行双重编码:

 if (!String.prototype.encodeHTML) { String.prototype.encodeHTML = function () { return this.replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&apos;'); }; } 

正如@Johan BW de Vries指出的那样,这将会对标签名称产生问题,我想澄清一下,我假定这只是用于value

相反,如果你想解码HTML实体1 ,请确保你解码&amp; &之后的一切,以便你不加倍解码任何实体:

 if (!String.prototype.decodeHTML) { String.prototype.decodeHTML = function () { return this.replace(/&apos;/g, "'") .replace(/&quot;/g, '"') .replace(/&gt;/g, '>') .replace(/&lt;/g, '<') .replace(/&amp;/g, '&'); }; } 

1只是基础知识,不包括&copy; ©或其他这样的事情


就图书馆而言。 Underscore.js (或者Lodash,如果你愿意)提供一个_.escape方法来执行这个function。

相同的结果可能会更有效一些:

 function escapeXml(unsafe) { return unsafe.replace(/[<>&'"]/g, function (c) { switch (c) { case '<': return '&lt;'; case '>': return '&gt;'; case '&': return '&amp;'; case '\'': return '&apos;'; case '"': return '&quot;'; } }); } 

如果你有jQuery,这里有一个简单的解决scheme:

  String.prototype.htmlEscape = function() { return $('<div/>').text(this.toString()).html(); }; 

像这样使用它:

"<foo&bar>".htmlEscape(); – > "&lt;foo&amp;bar&gt"

你可以使用下面的方法。 我已经添加了这个在原型更容易访问。 如果你调用两次或更多的方法,我也使用了负面预测,所以它不会弄乱事情。

用法:

  var original = "Hi&there"; var escaped = original.EncodeXMLEscapeChars(); //Hi&amp;there 

解码是在XMLparsing器中自动处理的。

方法 :

 //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, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"); OutPut = OutPut.replace(/&(?!(amp;)|(lt;)|(gt;)|(quot;)|(#39;)|(apos;))/g, "&amp;"); OutPut = OutPut.replace(/([^\\])((\\\\)*)\\(?![\\/{])/g, "$1\\\\$2"); //replaces odd backslash(\\) with even. } else { OutPut = ""; } return OutPut; }; 

从技术上讲,&,<和>不是有效的XML实体名称字符。 如果你不能相信关键的variables,你应该过滤出来。

如果你想让它们作为HTML实体转义,你可以使用像http://www.strictly-software.com/htmlencode这样的东西。;

我原来在生产代码中使用了可接受的答案,发现在使用过程中实际上非常慢。 这是一个更快的解决scheme(运行速度超过两倍):

  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("<>&")); //&lt;&gt;&amp; 

这很简单:

 sText = ("" + sText).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;");