[英]how to escape xml entities in javascript?
在 JavaScript(服務器端 nodejs)中,我正在編寫一個生成 xml 作為輸出的程序。
我通過連接一個字符串來構建 xml:
str += '<' + key + '>';
str += value;
str += '</' + key + '>';
問題是:如果value
包含像'&'
、 '>'
或'<'
這樣的字符怎么辦? 逃脫這些角色的最佳方法是什么?
或者是否有任何可以轉義 XML 實體的 javascript 庫?
HTML 編碼只是簡單地將&
、 "
、 '
、 <
和>
字符替換為其實體等效項。順序很重要,如果您不先替換&
字符,您將對一些實體進行雙重編碼:
if (!String.prototype.encodeHTML) {
String.prototype.encodeHTML = function () {
return this.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
};
}
正如@Johan BW 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只是基礎,不包括©
©
或其他類似的事情
就圖書館而言。 Underscore.js (或者Lodash ,如果你喜歡的話)提供了一個_.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, "$1\\\\$2"); //replaces odd backslash(\\) with even.
}
else {
OutPut = "";
}
return OutPut;
};
注意,如果 XML 中包含 XML,那么所有的正則表達式都不好。
而是在字符串上循環一次,並替換所有轉義字符。
這樣一來,你就不能兩次碾過同一個角色。
function _xmlAttributeEscape(inputString)
{
var output = [];
for (var i = 0; i < inputString.length; ++i)
{
switch (inputString[i])
{
case '&':
output.push("&");
break;
case '"':
output.push(""");
break;
case "<":
output.push("<");
break;
case ">":
output.push(">");
break;
default:
output.push(inputString[i]);
}
}
return output.join("");
}
我最初在生產代碼中使用了公認的答案,發現在大量使用時它實際上真的很慢。 這是一個更快的解決方案(以兩倍以上的速度運行):
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
}
如果之前有什么東西被轉義了,你可以試試這個,因為這不會像許多其他人一樣雙重轉義
function escape(text) {
return String(text).replace(/(['"<>&'])(\w+;)?/g, (match, char, escaped) => {
if(escaped)
return match
switch(char) {
case '\'': return '"'
case '"': return '''
case '<': return '<'
case '>': return '>'
case '&': return '&'
}
})
}
加上 ZZZZBov 的答案,我發現這更清晰,更易於閱讀:
const encodeXML = (str) =>
str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
此外,所有五個字符都可以在此處找到,例如: https ://www.sitemaps.org/protocol.html
請注意,這僅對值進行編碼(如其他人所述)。
既然我們有字符串插值和其他一些現代化,現在是時候進行更新了。 並使用對象查找,因為它確實應該。
const escapeXml = (unsafe) =>
unsafe.replace(/[<>&'"]/g, (c) => `&${({
'<': 'lt',
'>': 'gt',
'&': 'amp',
'\'': 'apos',
'"': 'quot'
})[c]};`);
從技術上講,&、< 和 > 不是有效的 XML 實體名稱字符。 如果您不能信任關鍵變量,則應將其過濾掉。
如果您希望它們作為 HTML 實體轉義,您可以使用類似http://www.strictly-software.com/htmlencode的內容。
這很簡單:
sText = ("" + sText).split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'");
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.