6

我环顾四周,但找不到一个只能转义特殊 XML 字符的内置 .Net 方法: <, >, &, 如果它不是标签。'"

例如,采用以下文本:

Test& <b>bold</b> <i>italic</i> <<Tag index="0" />

我希望将其转换为:

Test&amp; <b>bold</b> <i>italic</i> &lt;<Tag index="0" />

请注意,标签没有转义。我基本上需要将此值设置为 an InnerXMLXmlElement因此,必须保留这些标签。

我已经研究过实现我自己的解析器并StringBuilder尽可能地使用它来优化它,但它会变得非常讨厌。

我也知道可以接受的可以简化事情的标签(仅:br,b,i,u,blink,flash,Tag)。此外,这些标签可以是自闭合标签

(e.g. <u />)

或容器标签

(e.g. <u>...</u>)
4

3 回答 3

3

注意:这可能会被优化。这只是我为你快速敲门的东西。另请注意,我没有对标签本身进行任何验证。它只是在寻找包含在尖括号中的内容。<sometag label="I put an > here">如果在标签中找到尖括号(例如),它也会失败 。除此之外,我认为它应该做你所要求的。

namespace ConsoleApplication1
{
    using System;
    using System.Text.RegularExpressions;

    class Program
    {
        static void Main(string[] args)
        {
            // This is the test string.
            const string testString = "Test& <b>bold</b> <i>italic</i> <<Tag index=\"0\" />";

            // Do a regular expression search and replace. We're looking for a complete tag (which will be ignored) or
            // a character that needs escaping.
            string result = Regex.Replace(testString, @"(?'Tag'\<{1}[^\>\<]*[\>]{1})|(?'Ampy'\&[A-Za-z0-9]+;)|(?'Special'[\<\>\""\'\&])", (match) =>
                {
                    // If a special (escapable) character was found, replace it.
                    if (match.Groups["Special"].Success)
                    {
                        switch (match.Groups["Special"].Value)
                        {
                            case "<":
                                return "&lt;";
                            case ">":
                                return "&gt;";
                            case "\"":
                                return "&quot;";
                            case "\'":
                                return "&apos;";
                            case "&":
                                return "&amp;";
                            default:
                                return match.Groups["Special"].Value;
                        }
                    }

                    // Otherwise, just return what was found.
                    return match.Value;
                });

            // Show the result.
            Console.WriteLine("Test String: " + testString);
            Console.WriteLine("Result     : " + result);
            Console.ReadKey();
        }
    }
}
于 2012-12-19T22:54:21.773 回答
2

我个人认为这是不可能的,因为您确实在尝试修复格式错误的 HTML,因此您无法使用任何规则来确定要编码的内容和不编码的内容。

无论您以何种方式看待它,<<Tag index="0" />都不是有效的 HTML。

如果您知道实际的标签,您可以创建一个可以简化事情的白名单,但是您将不得不更具体地解决您的问题,我认为您无法在任何情况下解决这个问题。

实际上,您的文本中实际上可能没有任何随机<>乱七八糟的东西,这(可能)会大大简化问题,但是如果您真的想提出一个通用的解决方案....我希望你运气。

于 2012-12-19T22:40:37.143 回答
1

这是一个您可以使用的正则表达式,它将匹配任何无效的<>.

(\<(?! ?/?(?:b|i|br|u|blink|flash|Tag[^>]*))|(?<! ?/?(?:b|i|br|u|blink|flash|Tag[^>]*))\>)

我建议将有效的标记测试表达式放入一个变量中,然后围绕它构建其余部分。

var validTags = "b|i|br|u|blink|flash|Tag[^>]*";
var startTag = @"\<(?! ?/?(?:" + validTags + "))";
var endTag = @"(?<! ?/?(?:" + validTags + "))/>";

然后就做RegEx.Replace这些。

于 2012-12-19T23:19:21.623 回答