2016-07-16 142 views
0

我在一个文本文件中有数千行数据我想通过将它变成更容易搜索的东西来轻松搜索(我希望XML或其他类型的大数据结构,尽管我不确定它是否会对我所想的是最好的)。如何将.txt文件中的数据转换为xml? c#

的数据看起来像这样的每一行:

书31,托马斯,乔治,32,34,154

(每本书不是唯一的,他们是索引那么本书将有几个不同的条目列在其中,数字是他们列出的页面)

所以我有点失去了如何做到这一点,我想读取.txt文件,修剪掉所有空格和逗号,我基本上知道如何为它准备数据,bu我将如何以编程方式在xml中创建许多元素和值或填充其他大型数据结构?

+0

为什么XML?如果它是XML,搜索大量数据本身并不容易。 –

+0

我很乐意提供建议......我只需要让搜索特定名称更容易一些。 – Alexandre

+0

个人而言,我觉得这种问题是使用数据库的经典案例。我是[SQlite](https://www.sqlite.org/)的粉丝(也可在NuGet中获得)。您可以创建数据库,读取和解析文件,并为数据创建记录。然后你可以让数据库引擎为你搜索你的数据。还有很多其他的方法。 –

回答

2

如果您的CSV文件不会改变太多,结构稳定,你可以简单地把它解析到的对象的列表在启动时

private class BookInfo { 
    string title {get;set;} 
    string person {get;set;} 
    List<int> pages {get;set;} 
} 


private List<BookInfo> allbooks = new List<BookInfo>(); 

public void parse() { 
    var lines = File.ReadAllLines(filename); //you could also read the file line by line here to avoid reading the complete file into memory 
    foreach (var l in lines) { 
     var info = l.Split(',').Select(x=>x.Trim()).ToArray(); 
     var b = new BookInfo { 
      title = info[0], 
      person = info[1]+", " + info[2], 
      pages = info.Skip(3).Select(x=> int.Parse(x)).ToList() 
     }; 
     allbooks.Add(b); 
    } 
} 

然后你就可以轻松地与例如LINQ搜索allbooks列表。

编辑

现在,你已经澄清你的输入,我适应了解析一点点,以更好地满足您的需求。

如果你想要么titleperson更容易,你也可以对每个属性

var titleLookup = allbooks.ToLookup(x=> x.title); 
var personLookup = allbooks.ToLookup(x => x.person); 

所以personLookup["Thomas, George"]会给你所有bookinfos列表的创建查找搜索您的书目是提及“托马斯,乔治”和titleLookup["Book 31"]会给你一个“书31”的所有bookinfos列表,即该书中提到的所有人。

+0

这不是一个坏的解决方案!我不知道我是否会继续这样做,但它确实具有简单性。我应该更清楚一点,但是我所指的书是索引,所以每本书都会有多个与它相关的名字(数字是页码),但这仍然有效! – Alexandre

+1

@Alexandre查看我的更新回答 – derpirscher

+0

我对这种方法还有一个问题,我不确定需要使用它的每个实例读取文件的开销和等待时间。那么你怎么能保存现在全部在列表中的信息呢?只是在关闭工作时序列化它? – Alexandre

1

如果您希望将CSV文件转换为更容易搜索的内容,从而可以轻松搜索CSV文件,则可以将其转换为DataTable。

如果你想要的数据,你可以使用LINQ到XML搜索

下面的类生成两个数据表或XML数据格式。你可以通过分隔符,includeHeader或使用默认:

class CsvUtility 
{ 
    public DataTable Csv2DataTable(string fileName, bool includeHeader = false, char separator = ',') 
    { 
     IEnumerable<string> reader = File.ReadAllLines(fileName); 
     var data = new DataTable("Table"); 
     var headers = reader.First().Split(separator); 
     if (includeHeader) 
     { 
      foreach (var header in headers) 
      { 
       data.Columns.Add(header.Trim()); 
      } 
      reader = reader.Skip(1); 
     } 
     else 
     { 
      for (int index = 0; index < headers.Length; index++) 
      { 
       var header = "Field" + index; // headers[index]; 
       data.Columns.Add(header); 
      } 
     } 

     foreach (var row in reader) 
     { 
      if (row != null) data.Rows.Add(row.Split(separator)); 
     } 
     return data; 
    } 
    public string Csv2Xml(string fileName, bool includeHeader = false, char separator = ',') 
    { 
     var dt = Csv2DataTable(fileName, includeHeader, separator); 
     var stream = new StringWriter(); 
     dt.WriteXml(stream); 
     return stream.ToString(); 
    } 
} 

例如使用:

CsvUtility csv = new CsvUtility(); 
     var dt = csv.Csv2DataTable("f1.txt"); 

     // Search for string in any column 
     DataRow[] filteredRows = dt.Select("Field1 LIKE '%" + "Thomas" + "%'"); 

     //search in certain field 
     var filtered = dt.AsEnumerable().Where(r => r.Field<string>("Field1").Contains("Thomas")); 


     //generate xml 
     var xml= csv.Csv2Xml("f1.txt"); 
     Console.WriteLine(xml); 
/* 
    output of xml for your sample: 
    <DocumentElement> 
    <Table> 
     <Field0>Book 31</Field0> 
     <Field1> Thomas</Field1> 
     <Field2>George</Field2> 
     <Field3> 32</Field3> 
     <Field4> 34</Field4> 
     <Field5> 154</Field5> 
    </Table> 
</DocumentElement> 

*/ 
+0

这将如何与多个条目一起工作?你需要知道你正在寻找的信息的领域以找到它吗? – Alexandre

+0

如果第一行包含标题,则DataTable的列将被命名,您可以使用这些名称进行搜索。与和/或组合。 例如: 假设标题是:title,lastName,firstName,category1,category2,category3 var filteredRows = dt.Select(“lastName like'Thomas%'and firstName like'George%'”); var filteredRows = dt.Select(“lastName ='Thomas'and firstName ='George'”); –