如何在 JavaScript 中转义 XML 实体?

问题描述 投票:0回答:12

在 JavaScript(服务器端 NodeJS)中,我正在编写一个生成 XML 作为输出的程序。

我通过连接字符串来构建 XML:

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

问题是:如果

value
包含
'&'
'>'
'<'
等字符怎么办? 逃离这些角色的最佳方法是什么?

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

javascript
12个回答
140
投票

对于相同的结果,这可能会更有效一些:

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;';
        }
    });
}

135
投票

HTML 编码只是将

&
"
'
<
>
字符替换为其实体等效项。顺序很重要,如果您不首先替换
&
字符,您将对某些实体进行双重编码:

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 B.W. de Vries 指出,这会对标签名称产生问题,我想澄清一下,我假设这是用于

value
only

相反,如果您想解码 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
方法来执行此功能。


25
投票

如果您有 jQuery,这里有一个简单的解决方案:

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

像这样使用它:

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


8
投票

您可以使用以下方法。我已将其添加到原型中以便于访问。 我还使用了负前瞻,因此如果您调用该方法两次或更多次,它不会弄乱事情。

用途:

 var original = "Hi&there";
 var escaped = original.EncodeXMLEscapeChars();  //Hi&amp;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, "&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;
};

3
投票

注意,如果 XML 中有 XML,那么所有的正则表达式都不好。
相反,循环字符串一次,并替换所有转义字符。
这样,您就不能两次碰到同一个角色。

function _xmlAttributeEscape(inputString)
{
    var output = [];

    for (var i = 0; i < inputString.length; ++i)
    {
        switch (inputString[i])
        {
            case '&':
                output.push("&amp;");
                break;
            case '"':
                output.push("&quot;");
                break;
            case "<":
                output.push("&lt;");
                break;
            case ">":
                output.push("&gt;");
                break;
            default:
                output.push(inputString[i]);
        }


    }

    return output.join("");
}

2
投票

我最初在生产代码中使用了已接受的答案,发现大量使用时它实际上非常慢。这是一个更快的解决方案(以两倍以上的速度运行): 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;



2
投票

function encodeXML(s) { const dom = document.createElement('div') dom.textContent = s return dom.innerHTML }

参考


1
投票

const encodeXML = (str) => str .replace(/&/g, '&amp;') .replace(/</g, '&lt;') .replace(/>/g, '&gt;') .replace(/"/g, '&quot;') .replace(/'/g, '&apos;');

此外,所有五个字符都可以在这里找到,例如:
https://www.sitemaps.org/protocol.html

请注意,这仅对值进行编码(如其他人所述)。


1
投票

const escapeXml = (unsafe) => unsafe.replace(/[<>&'"]/g, (c) => `&${({ '<': 'lt', '>': 'gt', '&': 'amp', '\'': 'apos', '"': 'quot' })[c]};`);



0
投票
不是有效的 XML 实体名称字符。如果您不能信任关键变量,则应该将其过滤掉。

< and >如果您希望它们作为 HTML 实体转义,您可以使用类似

http://www.strictly-software.com/htmlencode

.


0
投票

function escape(text) { return String(text).replace(/(['"<>&'])(\w+;)?/g, (match, char, escaped) => { if(escaped) { return match; } switch(char) { case '\'': return '&apos;'; case '"': return '&quot;'; case '<': return '&lt;'; case '>': return '&gt;'; case '&': return '&amp;'; } }); }



-2
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.