搜索多个XML文件以获取字符串

时间:2012-05-09 12:08:34

标签: c# asp.net xml .net-3.5

我有一个包含400k + XML文档的文件夹以及更多文档,每个文件都以'ID'.xml命名,每个文件都属于特定用户。在SQL服务器数据库中,我使用XML文件中的“ID”与userID匹配,在userID中,我将XML文档与用户互连。用户可以附加无限数量的XML文档(但是假设最大的> 10k文档)

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

现在,每个用户都需要在属于她的XML文档中进行搜索,到目前为止我已经尝试过(循环遍历每个文件并使用streamreader读取它)太慢了。我不在乎,如果它读取并匹配整个文件与属性等,或只是每个元素中的文本。首先应该返回的是一个包含文件名中ID的列表。

这里最快最聪明的方法是什么?

7 个答案:

答案 0 :(得分:2)

我认为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);

输出结果相同,只是根据元素名称进行过滤的另一种方式。

答案 1 :(得分:2)

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

在解析Xml时,如果需要速度,则可以使用XmlReader,因为它比其他解析器执行得更好(大多数读取整个Xml文件,然后才能查询它们)。它只是向前的事实不应该是对这种情况的限制。

如果解析需要与磁盘I / O一样长,您可以尝试并行解析文件,这样一个线程可以等待读取文件,而另一个线程解析加载的数据。不过,我认为你不能让 赢得胜利。

还有什么是“太慢”,什么是可以接受的?随着时间的推移,许多文件的解决方案会变慢吗?

答案 2 :(得分:1)

使用LINQ to XML。

查看this文章。在msdn。

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

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

答案 3 :(得分:1)

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

例如: ID,tagName1,tagName2 xmlDocID,value1,value2

我的另一个问题是,为什么选择将xml文档存储在文件系统中。如果您使用的是SQL Server 2005/2008,它可以非常好地支持存储,搜索xml列(甚至索引xml中的某些值)

答案 4 :(得分:0)

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

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

如果这就是你正在做的事情,另一种选择就是获得grep这样的东西来为你做繁重的工作。使用“-l”参数对其进行修改,以指定您只对文件名感兴趣,并且您将获胜。 (有关更多用法示例,请参阅this link

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

Lucene.NET(和Lucene)支持增量索引。如果您可以经常重新打开索引以进行阅读,那么您可以整天将文档添加到索引中 - 您的搜索将与上次重新打开索引进行搜索时保​​持同步。