我正在用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中。当我运行程序时卡住了没有回报。另外,debuggin没有帮助,因为我无法读取值!在读取XML时似乎没有错误,好像我将读取值VALUES替换为它有效的ID。
例如,
ID = p.Element("ID").Value // Works
VALUES = p.Element("STRUCT").Element("VALUES").Value // Doesn"t work
由于VALUES节点在STRUCT节点内,我写了上面的代码。请说明问题出在哪里?
答案 0 :(得分:0)
LINQ-to-XML对c# string length limit以外的XML节点文本的最大长度没有限制。如果在解析XML时超过该限制,则会得到OutOfMemoryException
而不是挂起。
如果您的XML很大且包含许多元素,那么最可能的问题是,当您向其添加越来越多的文本时,TextBox
需要花费很长时间才能进行更新。具体做法是:
您要为文件中的每个<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());
请注意,如果您想要将文字附加到TextBox
或RichTextBox
,则应使用AppendText()
。有关说明,请参阅here或here。
如果您的XML文本非常庞大,TextBox
似乎在更新和渲染时会冻结,尽管只将文本设置为一次,您可能需要重新考虑您的设计。
一种可能是仅将前几百行文本添加到TextBox
(或者至少比文本框中可见的行数更多),然后如果用户滚动到最后,使用AppendText()
添加更多内容。
要开始使用,您可以查看