如何在 XML 中对特殊字符进行编码

本文关键字:特殊字符 编码 XML | 更新日期: 2023-09-27 17:57:09

我的字符串XML包含一系列特殊字符:

&
egrave;
&
rsquo;
&
rsquo;
&
rsquo;
&
ldquo;
&
rdquo;
&
rsquo
&
agrave;
&
agrave;

我需要替换数据库中插入字符串中的这个特殊字符,我尝试使用System.Net.WebUtility.HtmlEncode但没有成功,你能帮我吗?

string sql = "insert into rss (title, description, link, pubdate) values (?,?,?, " +
             " STR_TO_DATE(?, '%a, %d %b %Y %H:%i:%s GMT'));";
OdbcCommand command;
OdbcDataAdapter adpter = new OdbcDataAdapter();
connection.Open();
command = new OdbcCommand(sql, connection);
command.Parameters.AddWithValue("param1", System.Net.WebUtility.HtmlEncode(xmlTitle.InnerText.ToString()));
command.Parameters.AddWithValue("param2", System.Net.WebUtility.HtmlEncode(xmlDescription.InnerText.ToString()));
command.Parameters.AddWithValue("param3", System.Net.WebUtility.HtmlEncode(xmlLink.InnerText.ToString()));
command.Parameters.AddWithValue("param4", System.Net.WebUtility.HtmlEncode(xmlPubDate.InnerText.ToString()));
adpter.InsertCommand = command;
adpter.InsertCommand.ExecuteNonQuery();
connection.Close();

如何在 XML 中对特殊字符进行编码

可以使用本机 .NET 方法来转义文本中的特殊字符。当然,只有 5 个特殊字符,5 个 Replace() 调用可能会解决问题,但我相信必须内置一些东西。

"&"转换为"&"的示例

令人欣慰的是,我发现了一个本机方法,隐藏在SecurityElement类的内部。是的,没错 - SecurityElement.Escape(string s) 将转义您的字符串并使其 XML 安全。

这很重要,因为如果我们将数据复制或写入 Infopath 文本字段,则需要首先将其转义为非实体字符,如 "&" .

要替换为的 XML 字符无效

"<" to "&lt;"

">" to "&gt;"

"'"" to "&quot;"

"'" to "&apos;"

"&" to "&amp;"

命名空间是"System.Security"。请参考 : http://msdn2.microsoft.com/en-us/library/system.security.securityelement.escape(VS.80).aspx

另一个选项是自定义代码

public static string EscapeXml( this string s )
{
  string toxml = s;
  if ( !string.IsNullOrEmpty( toxml ) )
  {
    // replace literal values with entities
    toxml = toxml.Replace( "&", "&amp;" );
    toxml = toxml.Replace( "'", "&apos;" );
    toxml = toxml.Replace( "'"", "&quot;" );
    toxml = toxml.Replace( ">", "&gt;" );
    toxml = toxml.Replace( "<", "&lt;" );
  }
  return toxml;
}
public static string UnescapeXml( this string s )
{
  string unxml = s;
  if ( !string.IsNullOrEmpty( unxml ) )
  {
    // replace entities with literal values
    unxml = unxml.Replace( "&apos;", "'" );
    unxml = unxml.Replace( "&quot;", "'"" );
    unxml = unxml.Replace( "&gt;", ">" );
    unxml = unxml.Replace( "&lt;", "<" );
    unxml = unxml.Replace( "&amp;", "&" );
  }
  return unxml;
}
您可以使用 HttpUtility.HtmlDecode

或 .NET 4.0+ 您也可以使用 WebUtility.HtmlDecode

而不是System.Net.WebUtility.HtmlEncode你必须使用System.Net.WebUtility.HtmlDecode

您尝试的方法来看,还有其他 3 种方法可以做到这一点:

  1. 使用字符串。替换() 5 次
  2. 使用 System.Web.HttpUtility.HtmlEncode()
  3. System.Xml.XmlTextWriter

我可以解释每个案例,但我发现这个链接非常有用。

可以使用System.Xml.Linq.XElement在 XML 中对特殊字符进行编码。

喜欢这个:

var val = "test&<";
var node = new XElement("Node");
node.Value = val ?? node.Value;
Console.WriteLine(node.ToString());

输出:

"<节点>测试&<</节点>"

.NET 5+ 的现成 XML 转义函数:

[return: NotNullIfNotNull(nameof(s))]
static string? XmlEscape(string? s)
{
    if (string.IsNullOrEmpty(s))
        return s;
    var node = new XElement("X") { Value = s };
    return node.ToString()[3..^4];
}

使用示例:

Console.WriteLine(XmlEscape("Hello < & >"));

产生的输出:

Hello &lt; &amp; &gt;

Statement toxml = toxml.Replace( "&", "&amp;" );

这必须首先完成。 否则,当调用最后一个时,会将所有以前的"&"('或")替换为&;

简单代码:

    public static string ToXmlStr(string value) => String.IsNullOrEmpty(value) ? "" : value.Replace("&", "&amp;").Replace("'", "&apos;").Replace("'"", "&quot;").Replace(">", "&gt;").Replace("<", "&lt;");
    public static string FromXmlStr(string xmlStr) => String.IsNullOrEmpty(xmlStr) ? "" : xmlStr.Replace("&apos;", "'").Replace("&quot;", "'"").Replace("&gt;", ">").Replace("&lt;", "<").Replace("&amp;", "&");
    public static string ToMultilineXmlStr(string value) => String.IsNullOrEmpty(value) ? "" :
        value.Replace("'r", "").Split(''n').Aggregate(new StringBuilder(), (s, n) => s.Append("<p>").Append(ToXmlStr(n)).Append("</p>'n")).ToString();

请注意:对于xml中的多行值,通常需要将每行封装成<p> tag. So "<'&A'>'n<'&B'>" => "<p>&lt;&amp;A;&gt;</p><p>&lt;&amp;B;&gt;</p>"