【问题标题】:How to encode special characters in XML如何在 XML 中编码特殊字符
【发布时间】:2021-03-04 16:48:32
【问题描述】:

我的字符串 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();

【问题讨论】:

  • 存储在数据库中时是否需要对其进行编码?难道你不能简单地存储原始文本(不编码),然后如果/当你在 HTML 页面中编写它们时将它们编码回来?

标签: c# xml


【解决方案1】:

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

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

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

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

要替换的无效 XML 字符

"<" to "<"

">" to ">"

"\"" to """

"'" to "'"

"&" to "&"

命名空间是“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( "&", "&" );
    toxml = toxml.Replace( "'", "'" );
    toxml = toxml.Replace( "\"", """ );
    toxml = toxml.Replace( ">", ">" );
    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;
}

【讨论】:

  • 如果使用@DmytroKhmara 的自定义代码,toxml = toxml.Replace( "&amp;", "&amp;amp;" ); 需要成为EscapeXML 中的第一个替换。否则,您将转义所有其他转义字符中的与号。
  • 考虑使用 StringBuilder 来执行 Replace 调用。它会在原地完成它们,而不是剥离 5 个垃圾字符串。
【解决方案2】:

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

【讨论】:

  • 你的意思可能是HtmlEncode
【解决方案3】:

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

【讨论】:

  • 什么是我的 XML 包含类似
  • 使用 html.decode 会将其更改为 使用 XElement 或 XDocument 解析它时会抛出错误,因为属性 NAME 的双引号
【解决方案4】:

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

  1. 使用 string.Replace() 5 次
  2. 使用 System.Web.HttpUtility.HtmlEncode()
  3. System.Xml.XmlTextWriter

我可以解释每种情况,但我找到了this link to be mightily useful

【讨论】:

    【解决方案5】:

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

    这必须首先完成。否则,当最后调用它时,会将前面的所有“&”(' 或“)替换为 &amps;

    【讨论】:

      【解决方案6】:

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

      像这样:

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

      输出:

      "测试&<"

      【讨论】:

        【解决方案7】:

        简单代码:

            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 中的多行值,通常需要将每一行封装到 &lt;p&gt; tag. So "&lt;'&amp;A'&gt;\n&lt;'&amp;B'&gt;" =&gt; "&lt;p&gt;&amp;lt;&amp;amp;A;&amp;gt;&lt;/p&gt;&lt;p&gt;&amp;lt;&amp;amp;B;&amp;gt;&lt;/p&gt;"

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-06
          相关资源
          最近更新 更多