【问题标题】:Unescape characters in xml filexml文件中的转义字符
【发布时间】:2014-02-12 14:32:19
【问题描述】:

好吧,不幸的是,我无法访问无法通过 LoadXml 方法解析的 unescape char 附带的 xml 文件的源代码,我编写了几行代码来替换 xml 值中存在的特殊字符来转义字符.但是,我觉得没那么好。请帮助我改进它。

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 字符串分解为相等的小部分。请帮忙。

【问题讨论】:

  • 如果您知道正则表达式匹配未转义的位置,您可以使用CDATA 并将xml 重写为有效形式。
  • 是什么让你觉得你的“不太好”?只是性能问题?你得到的越具体,答案就越具体。
  • @C.Evenhuis 是的,性能问题。对于一般情况,我需要显着快速地改进它。好吧,平均情况就像它/软件行业中使用的 xml 文件的平均长度。因为它会检查每个值,所以性能会随着 xml 中出现的行数和值的数量而降低。

标签: c# xml regex


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 2020-01-19
    • 1970-01-01
    相关资源
    最近更新 更多