我有一个程序可以运行测试并生成包含所有结果的网格视图,还有一个XML日志文件。该程序还具有加载日志以复制网格视图的功能。
由于程序在执行时写入日志文件,如果崩溃,日志文件将缺少结束标记。我仍然希望能够加载这些XML文件,因为仍然有很多有价值的数据可以帮助我找出导致崩溃的原因。
我在考虑可能会浏览XML文件并关闭所有未关闭的XML标记,或者编写某种“Dirty”XML读取器,假装每个标记都已关闭。关于我能做什么或如何进行的任何想法?
编辑:
<Root>
<Parent>
<Child Name="One">
<Foo>...</Foo>
<Bar>...</Bar>
<Baz>...</Baz>
</Child>
<Child Name="Two">
<Foo>...</Foo>
<Bar>...</Bar>
!-- Crash happens here --!
从此我仍然希望产生
Child Foo Bar Baz
One ... ... ...
Two ... ... /
答案 0 :(得分:5)
据推测它一直有效,直到它被截断...所以使用XmlReader
可以工作......只要准备好在它到达截断点时处理它。
现在XmlReader
API并不是非常令人愉快(IMO)所以你可能想要转移到一些有趣数据的开头(这本身就必须完整),然后调用{{3}方法以简单易用的形式获取数据。然后移动到下一个元素的开头并执行相同的操作等。
示例代码:
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
class Program
{
static void Main(string[] args)
{
using (XmlReader reader = XmlReader.Create("test.xml"))
{
while (true)
{
while (reader.NodeType != XmlNodeType.Element ||
reader.LocalName != "Child")
{
if (!reader.Read())
{
Console.WriteLine("Finished!");
}
}
XElement element = (XElement) XNode.ReadFrom(reader);
Console.WriteLine("Got child: {0}", element.Value);
}
}
}
}
示例XML:
<Root>
<Parent>
<Child>First child</Child>
<Child>Second child</Child>
<Child>Broken
示例输出:
得到了孩子:第一个孩子 得到了孩子:第二个孩子
Unhandled Exception: System.Xml.XmlException: Unexpected end of file has occurred
The following elements are not closed: Child, Parent, Root. Line 5, position 18.
at System.Xml.XmlTextReaderImpl.Throw(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseElementContent()
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r)
at System.Xml.Linq.XContainer.ReadContentFrom(XmlReader r, LoadOptions o)
at System.Xml.Linq.XElement.ReadElementFrom(XmlReader r, LoadOptions o)
at System.Xml.Linq.XNode.ReadFrom(XmlReader reader)
at Program.Main(String[] args)
所以显然你想要捕获异常,但是你可以看到它设法正确读取了前两个元素。
答案 1 :(得分:4)
作为最后的手段,根据您的操作,您可以使用HTML阅读器,例如HtmlAgilityPack(Nuget page)或SGMLReader。 SGMLReader实际上会将它转换为XmlDocument,因此可能更符合您的要求。
当然,HTML不是XML,因此您可以获得使用此方法时获得的内容。
答案 2 :(得分:0)
框架中没有这样的东西,默认情况下没有这样做,也没有一个好的解决方案可以以某种方式解析通用的无效xml。
你可以做的最明智的事情是在开始阅读之前修复XML。由于只有结束被切断,你应该能够找出所有打开的标签并关闭它们。