如何在javascript中转义xml实体?

时间:2011-10-27 16:04:10

标签: javascript

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

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

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

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

或者是否有任何javascript库可以绕过XML实体?

9 个答案:

答案 0 :(得分:97)

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

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

答案 1 :(得分:87)

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

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

答案 2 :(得分:19)

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

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

像这样使用:

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

答案 3 :(得分:6)

您可以使用以下方法。我在原型中添加了这个以便于访问。 我也使用了负向前瞻,所以如果你把方法调用两次或更多,它就不会弄乱。

<强>用法:

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

答案 4 :(得分:1)

我最初在生产代码中使用了已接受的答案,并发现在大量使用时它实际上非常慢。这是一个很多更快的解决方案(运行速度超过两倍):

   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;

答案 5 :(得分:1)

警告,如果您在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("");
}

答案 6 :(得分:0)

技术上,&amp;,&lt;和&gt;不是有效的XML实体名称字符。如果您不能信任密钥变量,则应将其过滤掉。

如果您希望将它们转义为HTML实体,则可以使用http://www.strictly-software.com/htmlencode

之类的内容

答案 7 :(得分:0)

如果从以前逃脱了一些东西,您可以尝试一下,因为这样不会像其他许多东西一样使逃脱

import csv
with open('nba.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    data = []
    for row in reader:
        print(row['Name'], row['Salary'])

答案 8 :(得分:-1)

这很简单:

<?xml version="1.0" encoding="utf-8"?>

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardBackgroundColor="#777777"
    card_view:cardCornerRadius="0dp"
    card_view:cardElevation="3dp"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:gravity="center_vertical|center_horizontal"
        android:orientation="horizontal"
        android:weightSum="10">

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="3">

            <ImageView
                android:id="@+id/thumbImageView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/soul_bg" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_weight="7">

            <TableLayout
                android:id="@+id/tableLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:stretchColumns="0,1,2"
                android:weightSum="6">

                <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="3"
                    android:textColor="#FFF"
                    android:weightSum="3">

                    <TextView
                        android:id="@+id/nameTextView"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:text="Name:"
                        android:textColor="#FFF" />

                    <TextView
                        android:id="@+id/hpTextView"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:text="HP:"
                        android:textColor="#FFF" />

                    <TextView
                        android:id="@+id/atkTextView"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:text="ATK:"
                        android:textColor="#FFF" />
                </TableRow>

                <TableRow
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:layout_weight="3"
                    android:textColor="#FFF"
                    android:weightSum="3">

                    <TextView
                        android:id="@+id/typeTextView"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:text="Race:"
                        android:textColor="#FFF" />

                    <TextView
                        android:id="@+id/defTextView"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:text="DEF"
                        android:textColor="#FFF" />

                    <TextView
                        android:id="@+id/wisTextView"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        android:text="WIS"
                        android:textColor="#FFF" />
                </TableRow>
            </TableLayout>
        </LinearLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>