什么是通过xml进行搜索的最快方法

时间:2011-03-02 20:31:56

标签: c# xml search

假设我有一个XML文件,我用作本地数据库,就像这样):

<root>
 <address>
  <firstName></firstName>
  <lastName></lastName>
  <phone></phone>
 </address>
</root>

我有几个问题:
1. 在first中包含'er'的XML中查找地址(或地址)的最快方法是什么?
2. 是否可以在内存中没有完整加载XML文件?

P.S。我不是在寻找XML文件替代品,理想情况下我需要一个不依赖于XML文件中地址数的搜索。但我是现实主义者,在我看来,这是不可能的。

更新 我正在使用.net 4
感谢您的建议,但它比实际更科学。我可能正在寻找比linq和xmltextreader更快的方法。

6 个答案:

答案 0 :(得分:9)

LINQ to Xml非常好用:

XDocument doc = XDocument.Load("myfile.xml");
var addresses = from address in doc.Root.Elements("address")
                where address.Element("firstName").Value.Contains("er")
                select address;

更新:尝试在StackOverflow上查看此问题:Best way to search data in xml files?

Marc Gravell接受的答案使用SQL索引:

  

首先:xml文件有多大? XmlDocument不会扩展为“巨大”......但可以处理“大”OK。

     

第二:你可以把数据放一下吗?   进入常规数据库结构   (也许是SQL Server Express Edition),   索引它,并通过常规TSQL访问?   这通常会胜过xpath   搜索。同样,如果它是结构化的,   SQL Server 2005及更高版本支持   xml数据类型,粉碎数据 -   这允许您索引和查询xml   没有数据库中的数据   内存中的整个DOM(它   将xpath转换为关系   查询)。

更新2:另请阅读上一个问题所采用的另一个链接,该链接解释了XML结构如何影响效果:http://www.15seconds.com/issue/010410.htm

答案 1 :(得分:2)

如果您使用的是.NET 3.5+,请考虑使用LINQ To XML

一些示例代码可以让您有所了解:(以下代码从文章中解放/修改)

IEnumerable<string> addresses =
    from inv in customer.Descendants("Invoice")
    where inv.Attribute("ProductName").StartsWith("er")
    select (string) inv.Attribute("StreetAddress");

答案 2 :(得分:2)

那么XmlReader呢? 我认为这可能是最快的方式......

我尝试了大约110 MB的文件,花了大约1,1秒。 与LinqToXML(上面)相同的文件大约需要3秒。

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
XmlReader reader = XmlReader.Create("C:\\Temp\\items.xml", settings);

String firstName = "", lastName = "", phone = "";
String lastTagName = "";
Boolean bItemFound = false;
long nCounter = 0;

Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();

reader.MoveToContent();
// Parse the file and display each of the nodes.
while (reader.Read())
{
    switch (reader.NodeType)
    {
        case XmlNodeType.Element:
            //Console.Write("<{0}>", reader.Name);

            lastTagName = reader.Name;

            if (lastTagName ==  "address")
                nCounter++;

            break;
        case XmlNodeType.Text:
            //Console.Write(reader.Value);
            switch (lastTagName)
            {
               case "firstName":
                    firstName = reader.Value.ToString();
                    bItemFound = firstName.Contains("97331");
                    break;
                case "lastName":
                    lastName = reader.Value.ToString();
                    break;
                case "phone":
                    phone = reader.Value.ToString();
                    break;
            }
            break;
        case XmlNodeType.CDATA:
            //Console.Write("<![CDATA[{0}]]>", reader.Value);
            break;
        case XmlNodeType.ProcessingInstruction:
            //Console.Write("<?{0} {1}?>", reader.Name, reader.Value);
            break;
        case XmlNodeType.Comment:
            //Console.Write("<!--{0}-->", reader.Value);
            break;
        case XmlNodeType.XmlDeclaration:
            //Console.Write("<?xml version='1.0'?>");
            break;
        case XmlNodeType.Document:
        case XmlNodeType.DocumentType:
            //Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
            break;
        case XmlNodeType.EntityReference:
            //Console.Write(reader.Name);
            break;
        case XmlNodeType.EndElement:
            //Console.Write("</{0}>", reader.Name);
            break;
    }

    if (bItemFound)
    {
        Console.Write("{0}\n{1}\n{2}\n", firstName, lastName, phone);
        bItemFound = false;
    }
}

stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
    ts.Hours, ts.Minutes, ts.Seconds,
    ts.Milliseconds / 10);
Console.WriteLine("RunTime " + elapsedTime);
Console.WriteLine("Searched items: {0}", nCounter);

Console.ReadKey();

答案 3 :(得分:1)

如果您不想将整个文件读入内存,可以使用XmlTextReader。这样的解决方案可能运行得更快,但它将涉及更多编码。

答案 4 :(得分:1)

我担心你可能想要优化可能不需要它的东西。我们在谈论多少个电子邮件地址?大多数情况下,您将阅读输入并构建一个支持您将运行的查询类型的结构。

有些树可以在log(n)时间内获得您正在寻找的那种结果。而且你甚至可以在少量内存中存储大量地址。

答案 5 :(得分:1)

如果您真的不需要在服务器端执行此操作,则可以使用正则表达式执行此操作。但是我认为在memmory上加载XML会更快......