在多个 XML 文件中搜索字符串

本文关键字:搜索 字符串 文件 XML | 更新日期: 2023-09-27 18:33:33

我有一个文件夹,里面有400k+ XML文档,还有更多,每个文件都以"ID".xml命名,每个文件都属于一个特定的用户。在SQL服务器数据库中,我有XML文件中的"ID"与用户ID匹配,这是我将XML文档与用户互连的地方。用户可以附加无限数量的XML文档(但假设最多>10k个文档)

所有 XML 文档都有一些通用元素,但结构可能会略有不同。

现在,每个

用户都需要在属于她的XML文档中进行搜索,而到目前为止我尝试过的(循环访问每个文件并使用流阅读器读取)太慢了。我不在乎,它是否读取并使用属性等匹配整个文件,或者只是每个元素中的文本。首先应该返回的是一个列表,其中包含文件名中的 ID。

如果有的话,这里最快、最聪明的方法是什么?

在多个 XML 文件中搜索字符串

我认为LINQ-to-XML可能是你想要的方向。

假设您知道所需标签的名称,您将能够搜索这些特定元素并返回值。

var xDoc = XDocument.Load("yourFile.xml");
var result = from dec in xDoc.Descendants()
             where dec.Name == "tagName"
             select dec.Value;

然后,results将包含具有与"tagName"匹配的名称的任何 XML 标记的值的IEnumerable

查询也可以这样编写:

var result = from dec in xDoc.Decendants("tagName")
             select dec.Value;

或者这个:

var result = xDoc.Descendants("tagName").Select(tag => tag.Value);

输出将是相同的,只是根据元素名称进行过滤的不同方法。

你必须打开每个包含相关数据的文件,如果你不知道哪些文件包含它,你必须打开所有可能匹配的文件。因此,唯一的性能提升是在解析例程中。

解析 XML 时,如果需要速度,则可以使用该XmlReader,因为它的性能比其他解析器更好(大多数解析器在查询它们之前会读取整个 Xml 文件)。它仅向前的事实不应成为这种情况的限制。

如果解析花费的时间与磁盘 I/O 一样长,则可以尝试并行解析文件,以便一个线程可以等待读取文件,而另一个线程可以分析加载的数据。不过,我不认为你能在那里取得那么大的胜利。

还有什么是"太慢",什么是可以接受的?这种包含许多文件的解决方案会随着时间的推移而变慢吗?

使用 LINQ to XML。

看看这篇文章。 在MSDN那边。

XDocument doc = XDocument.Load("C:'file.xml");

并且不要忘记读取这么多文件总是很慢,您可以尝试编写多线程程序......

如果我

理解正确,您不想为特定用户打开每个 xml 文件,因为无论您使用 linq to xml 还是其他方法,它都太慢了。您是否考虑过在 xml 文件和关系数据库(标记)中保存一些值(以及 xml ID)。在这种情况下,您可以先在数据库中搜索某些值,然后仅选择包含搜索值的 xml 文件?

例如:ID, 标签名称 1, 标签名称 2xmlDocID, 值 1, 值 2

我的另一个问题是,为什么选择将XML文档存储在文件系统中。如果您使用的是SQL Server 2005/2008,它对存储,搜索xml列(甚至为xml中的某些值编制索引)提供了很好的支持。

您是否只是在某处查找内容中具有特定字符串的文件?

警告 - 不是纯 .NET 解决方案。 如果这让你感到害怕,那就坚持其他答案。:)

如果这就是你正在做的事情,另一种选择是让像 grep 这样的东西为你做繁重的工作。 用"-l"参数来指定你只对文件名感兴趣,并且你是一个赢家。 (有关更多使用示例,请参阅此链接)

L.B 已经提出了一个有效的观点。在这种情况下,Lucene.Net(或任何索引器)是必须的。它会在所有搜索中为您提供稳定(非常快)的性能。这是索引器的主要优势之一,可以处理非常大量的任意数据。

或者有什么理由,为什么你不使用Lucene?

Lucene.NET(和Lucene)支持增量索引。如果可以每隔一段时间重新打开索引进行阅读,那么可以整天不断向索引中添加文档 - 您的搜索将与上次重新打开索引进行搜索时保持同步。