将字符实体转换为它们的Unicode等价物

14

我在数据库中有HTML编码的字符串,但许多字符实体不仅仅是标准的&<。例如“—等实体。不幸的是,我们需要将这些数据提供给基于Flash的RSS阅读器,而Flash无法读取这些实体,但它们可以读取Unicode等效项(例如“)。

使用.Net 4.0,是否有任何实用程序方法可将HTML编码的字符串转换为使用Unicode编码的字符实体?

这里有一个更好的例子。数据库中有像这样的HTML字符串:<p>John &amp; Sarah went to see $ldquo;Scream 4$rdquo;.</p>,我需要在<description>标记内输出的rss/xml文档是:&lt;p&gt;John &amp;#38; Sarah went to see &amp;#8220;Scream 4&amp;#8221;.&lt;/p&gt;

我正在使用XmlTextWriter从数据库记录创建xml文档,类似于此示例代码http://www.dotnettutorials.com/tutorials/advanced/rss-feed-asp-net-csharp.aspx

因此,我需要将来自数据库的HTML字符串中的所有字符实体替换为它们的Unicode等效项,因为基于Flash的RSS阅读器不认识除&amp;之外的任何实体。


你确定你首先需要字符“实体”吗?为什么不只使用实际的Unicode“字符”? - Pekka
4个回答

7

我的第一个想法是,你的RSS阅读器是否能够接受实际字符?如果可以,你可以使用HtmlDecode并直接进行馈送。

如果你确实需要将其转换为数字表示形式,你可以解析出每个实体,HtmlDecode它,然后将其转换为int以获取十进制unicode值。然后重新插入到字符串中。

编辑: 下面是一些示例代码(未经测试,但可以理解):

string input = "Something with &mdash; or other character entities.";
StringBuilder output = new StringBuilder(input.Length);

for (int i = 0; i < input.Length; i++)
{
    if (input[i] == '&')
    {
        int startOfEntity = i; // just for easier reading
        int endOfEntity = input.IndexOf(';', startOfEntity);
        string entity = input.Substring(startOfEntity, endOfEntity - startOfEntity);
        int unicodeNumber = (int)(HttpUtility.HtmlDecode(entity)[0]);
        output.Append("&#" + unicodeNumber + ";");
        i = endOfEntity; // continue parsing after the end of the entity
    }
    else
        output.Append(input[i]);
}

我可能在某个地方有一个偏移量错误,但应该很接近。


谢谢你,我相信它会起作用。你说得对,使用HtmlDecode将其输入到Flash Rss阅读器中,但该代码在我们客户的控制下,我不认为他们真正知道自己在做什么。 - Dan
@Dan 听起来像是一个典型的客户 :) - ThatMatthew
这里有另一个解决方案:https://dev59.com/EmYr5IYBdhLWcg3wqr_o#24515287,使用正则表达式。 - Mark_Gibson
我在Xamarin中使用了WebUtility - William Grand

5

你觉得 HttpUtility.HtmlDecode 可以满足你的需求吗?

我知道它不会将字符转换为相应的unicode实体,而是将其转换为unicode。你需要转换为相应的unicode实体有特殊的原因吗?

更新编辑


        string test = "<p>John &amp; Sarah went to see &ldquo;Scream 4&rdquo;.</p>";
        string decode = HttpUtility.HtmlDecode(test);
        string encode = HttpUtility.HtmlEncode(decode);

        StringBuilder builder = new StringBuilder();
        foreach (char c in encode)
        {
            if ((int)c > 127)
            {
                builder.Append("&#");
                builder.Append((int)c);
                builder.Append(";");
            }
            else
            {
                builder.Append(c);
            }
        }
        string result = builder.ToString();

你应该编辑你的答案而不是在评论区留下备注。 - ChrisWue
不,HtmlDecode不起作用。这仍然需要是一个有效的RSS订阅源,其中字符被正确编码,但我们的客户还希望将此RSS订阅源用于基于Flash的广告网站。正如我在问题中所说的,Flash无法读取这些不常见的字符实体,但它可以读取基于Unicode编码的等效字符。 - Dan
1
很遗憾,这个方法不起作用,因为它将所有非字母数字字符(包括所有HTML标签,如尖括号等)编码为字符实体。我想我应该提供一个更好的例子(请参见上文)。感谢您的尝试,我会继续尝试您的代码,看看能否让它起作用。 - Dan

1

你可以从W3C下载适当的HTML和/或XHTML DTD的本地副本。然后设置一个XmlResolver并使用它来展开文档中找到的任何实体。

您可以使用正则表达式查找/展开实体,但这将不了解上下文(例如,在CDATA部分中的任何内容都不应该被展开)。


0

这可能会帮助您将输入路径放入文本框中

        try
        {
            FileInfo n = new FileInfo(textBox1.Text);
            string initContent = File.ReadAllText(textBox1.Text);
            int contentLength = initContent.Length;
            Match m;

            while ((m = Regex.Match(initContent, "[^a-zA-Z0-9<>/\\s(&#\\d+;)-]")).Value != String.Empty)
                initContent = initContent.Remove(m.Index, 1).Insert(m.Index, string.Format("&#{0};", (int)m.Value[0]));

            File.WriteAllText("outputpath", initContent);
        }

        catch (System.Exception excep)
        {

            MessageBox.Show(excep.Message);

        }



    }

它只替换单个文件,我想要替换多个文件,有人可以帮忙吗? - user2753776

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接