XML 另一个元素内的元素值卡在调试中,没有 return

XML Element value inside another Element gets stuck in debug, no return

我正在用 C# 编写 XML 解析器 (LINQ to XML)。以下是 XML 结构的示例:

<ASB CATEGORY="TUBE">
  <VERSION>700114d2fefesdse34be9cab26a</VERSION>
  <ID>106107</ID>
  <STRUCT>
    <VALUES>9.19 48.491, 9.372 48.56555, 9.4222 48.57472, 9.62361111 48.64833333, 9.74722222 48.680833, 9.74622531 48.665604, 9.744127737 48.65018037, 9.7410232 48.63496203183, 9.7369276269873 48.61984372, 9.73361111 48.60972222, 9.6255556 48.5625, 9.1538889 48.4489, 9.19111 48.491111111</VALUES>
  </STRUCT>
</ASB>

这是提取值的 C# 代码片段:

string strAppPath = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
XDocument xdoc = XDocument.Load(strAppPath + "\database\test.xml");
xdoc.Descendants("ASB").Select(p => new {
    CATEGORY = p.Attribute("CATEGORY").Value,
    VALUES = p.Element("STRUCT").Element("VALUES").Value
}).ToList().ForEach(p => {
    textBoxLog.Text += "CATEGORY: " + p.CATEGORY + System.Environment.NewLine + p.VALUES + System.Environment.NewLine + System.Environment.NewLine;
});

这里的值都打印在textBoxLog TextBox中。当我 运行 时,程序卡住了,没有 return。 debuggin 也没有帮助,因为我无法读取这些值!阅读 XML 时似乎没有错误,就好像我用有效的 ID 替换阅读值 VALUES 一样。

例如,

ID = p.Element("ID").Value // Works
VALUES = p.Element("STRUCT").Element("VALUES").Value // Doesn"t work

由于 VALUES 节点位于 STRUCT 节点内,我想编写上面的代码。请指出问题出在哪里?

LINQ-to-XML 对 XML 节点文本的最大长度没有限制,而不是 c# string length limit. If you exceed that limit while parsing XML you will get an OutOfMemoryException 而不是挂起。

如果您的 XML 很大且元素很多,那么最可能的问题是您的 TextBox 需要很长时间才能更新,因为您向其中添加了越来越多的文本。具体来说:

  1. 您正在为文件中的每个 <ASB> 设置一次 TextBox.Text。这将导致文本框的多次更新和重绘,可能会被消息淹没,长时间冻结 GUI 并导致明显的挂起。

    相反,您应该在 StringBuilder 中构建文本并仅设置一次 TextBox.Text

    var sb = new StringBuilder();
    foreach (var p in xdoc.Descendants("ASB"))
    {
        var CATEGORY = (string)p.Attribute("CATEGORY");
        var VALUES = (string)p.Element("STRUCT").Element("VALUES");
        sb.Append("CATEGORY: ").Append(CATEGORY).AppendLine().AppendFormat(VALUES).AppendLine().AppendLine();
    }
    
    textBoxLog.Text = sb.ToString();
    
    // Or if you want to add to pre-existing text, do
    // textBoxLog.AppendText(sb.ToString());
    

    请注意,如果您想将文本附加到 TextBoxRichTextBox,您应该使用 AppendText(). For an explanation, see here or .

  2. 如果您的 XML 文本太大,以至于 TextBox 似乎在更新和呈现自身时冻结,尽管只设置了一次文本,您可能需要重新想想你的设计。

    一种可能是仅将前几百行文本添加到 TextBox(或者至少,多于文本框中可见的行数),然后如果用户滚动到最后,使用 AppendText().

    添加更多

    要开始使用,您可以查看

    • Winforms RichTextBox: How can I determine how many lines of text are visible?.

    • Determine when textbox has been scrolled to the end.

    • Get current scroll position from rich text box control?.

    • How to detect if a scrollbar is or is not at the end of a richtextbox (vb.net).