在C#中以编程方式检查XML文件格式良好的最快方法是什么?

我有大批手动更新的XHTML文件。 在更新的审查阶段,我想以编程方式检查文件的格式。 我目前正在使用XmlReader ,但平均CPU所需的时间比我预期的要长得多。

XHTML文件的大小范围为4KB到40KB,每个文件的validation需要几秒钟。 检查是必不可少的,但我希望尽可能缩短时间,因为在将文件读入下一个流程步骤时执行检查。

有没有更快的方法来进行简单的XML格式检查? 也许使用外部XML库?


我可以确认使用XmlReadervalidation“常规”基于XML的内容是非常快速的,并且正如所建议的那样,问题似乎与每次validation文件时读取XHTML DTD的事实有关。

 

请注意,除了DTD之外,还会下载相应的.ent文件(xhtml-lat1.ent,xhtml-symbol.ent,xhtml-special.ent)。

由于完全忽略DTD并不是XHTML的真正选择,因为良好的格式与允许的HTML实体密切相关(例如,当我们忽略DTD时,会立即引入validation错误)。


通过使用建议的自定义XmlResolver ,结合DTD和实体文件的本地(嵌入)副本,解决了该问题。

一旦我清理了代码,我会在这里发布解决方案

我希望带有while(reader.Read)() {} XmlReader将是最快的托管方法。 读取40KB肯定不需要几秒钟 ……您使用的输入方法是什么?

你可能有一些外部(架构等)实体要解决? 如果是这样,您可以编写一个使用本地缓存模式而不是远程获取的自定义XmlResolver (通过XmlReaderSettings设置)…

以下几乎立即执行~300KB:

  using(MemoryStream ms = new MemoryStream()) { XmlWriterSettings settings = new XmlWriterSettings(); settings.CloseOutput = false; using (XmlWriter writer = XmlWriter.Create(ms, settings)) { writer.WriteStartElement("xml"); for (int i = 0; i < 15000; i++) { writer.WriteElementString("value", i.ToString()); } writer.WriteEndElement(); } Console.WriteLine(ms.Length + " bytes"); ms.Position = 0; int nodes = 0; Stopwatch watch = Stopwatch.StartNew(); using (XmlReader reader = XmlReader.Create(ms)) { while (reader.Read()) { nodes++; } } watch.Stop(); Console.WriteLine("{0} nodes in {1}ms", nodes, watch.ElapsedMilliseconds); } 

通过传入具有ConformanceLevel.DocumentXmlReader对象来创建XmlReader对象。

这将validation良好的forms。

这篇MSDN文章应该解释细节。

在我相当普通的笔记本电脑上,使用XmlReader从头到尾读取250K XML文档需要6毫秒。 除了解析XML之外的其他东西是罪魁祸首。

我知道即时发布,但我认为这可能是一个解决方案

  1. 使用HTML Tidy来清除你的xml。 设置删除doctype的选项
  2. 然后从整理中读取生成的xhtml / xml。

这是相同的代码

 public void GetDocumentStructure(int documentID) { string scmRepoPath = ConfigurationManager.AppSettings["SCMRepositoryFolder"]; string docFilePath = scmRepoPath + "\\" + documentID.ToString() + ".xml"; string docFilePath2 = scmRepoPath + "\\" + documentID.ToString() + "_clean.xml"; Tidy tidy = new Tidy(); tidy.Options.MakeClean = true; tidy.Options.NumEntities = true; tidy.Options.Xhtml = true; // this option removes the DTD on the generated output of Tidy tidy.Options.DocType = DocType.Omit; FileStream input = new FileStream(docFilePath, FileMode.Open); MemoryStream output = new MemoryStream(); TidyMessageCollection msgs = new TidyMessageCollection(); tidy.Parse(input, output, msgs); output.Seek(0, SeekOrigin.Begin); XmlReader rd = XmlReader.Create(output); int node = 0; System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew(); while (rd.Read()) { ++node; } watch.Stop(); Console.WriteLine("Duration was : " + watch.Elapsed.ToString()); } 

正如其他人提到的,瓶颈很可能不是XmlReader。

检查在没有stringbuilder的情况下是否会碰巧执行大量字符串连接。

这真的可以打动你的表现。

就个人而言,我很懒…所以我寻找已经解决问题的.NET库。 尝试使用DataSet.ReadXML()函数并捕获exception。 它在解释XML格式错误方面做得非常出色。