xml文件中的Unescape字符

时间:2014-02-12 14:32:19

标签: c# xml regex

好吧,遗憾的是我没有任何访问xml文件的源代码,该文件附带了无法通过LoadXml方法解析的unescape char,我编写了几行代码来替换xml值中存在的特殊字符以逃避char 。但是,我认为这不是那么好。请帮我改进一下。

private bool XmlEscaper(string inputXml, out string escapableXml)
    {
        bool isSuccess = true;
        escapableXml = string.Empty;
        StringBuilder xmlReconstruct = new StringBuilder();

        try
        {
            string firstFilter = Regex.Replace(inputXml, @"([\n\t\r\f\v])", string.Empty, RegexOptions.Multiline);

            string[] secondFilter = firstFilter.Split(new String[] { @">" }, StringSplitOptions.None);

            ///***
            ///final filtration: separate every 
            ///node and value independently,
            ///transform unescape characters and
            ///reconstruct the xml
            ///***
            for (int i = 0; i < secondFilter.Length - 1; i++)
            {
                secondFilter[i] = String.Concat(secondFilter[i], ">");

                if (!secondFilter[i].StartsWith("<") && !secondFilter[i + 1].StartsWith("</") && !Regex.IsMatch(secondFilter[i], @"(<)(/)"))
                {
                    string temp = secondFilter[i + 1];
                    string[] cap = temp.Split(new String[] { @"</" }, StringSplitOptions.None);
                    secondFilter[i] = String.Concat(secondFilter[i], cap[0]);
                    secondFilter[i + 1] = String.Concat("</", cap[1]);
                }

                if (Regex.IsMatch(secondFilter[i], @"(<)(/)") && !secondFilter[i].StartsWith("</"))
                {
                    string[] split = secondFilter[i].Split(new String[] { @"</" }, StringSplitOptions.None);

                    split[0] = System.Security.SecurityElement.Escape(split[0]);
                    xmlReconstruct.Append(split[0]);
                    xmlReconstruct.Append(String.Concat("</", split[1]));
                }
                else
                {
                    xmlReconstruct.Append(secondFilter[i]);
                }
            }
            escapableXml = xmlReconstruct.ToString();
        }
        catch (Exception ex)
        {
            isSuccess = false;
        }

        return isSuccess;
    }

好吧,我尝试了56000行的xml文件,不是很好但是确实有效,但有没有办法改进代码,循环运行很长时间。好吧,我们可以将xml字符串分成小部分。请帮忙。

1 个答案:

答案 0 :(得分:0)

您可以通过避免一些堆内存分配来加快速度,并且不要使用Regex进行简单搜索。例如:

  • 设置xmlReconstruct的初始容量,因为StringBuilder对象默认为16,并根据需要加倍:StringBuilder xmlReconstruct = new StringBuilder(inputXml.Length);
  • 使用Regex.Matches代替String.Split,然后处理每个返回的Match对象。
  • 使用String.Contains代替Regex.IsMatch
  • 如果可能,只使用xmlReconstruct.Append;避免String.Concat
  • 如果您正在处理多个文件,请在调用Regex之前初始化任何XmlEscaper对象