2016-07-16 300 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'」); –

相關問題