2014-11-02 32 views
2

我需要從基於一些標準
我的XML是一個XML文件,總結值求和值如下如何從一個XML文件,根據一定的標準

<?xml version="1.0" encoding="utf-8"?> 
<transactions> 
    <transcation ID="1"> 
     <BankName>ABC</BankName> 
     <TemplatModel>CT1</TemplatModel> 
     <Date>12/12/2014</Date> 
     <Payeename>xyz</Payeename> 
     <Amount>200</Amount> 
    </transcation> 
    <transcation ID="2"> 
     <BankName>EFG</BankName> 
     <TemplatModel>CT2</TemplatModel> 
     <Date>12/12/2014</Date> 
     <Payeename>xyz</Payeename> 
     <Amount>100</Amount> 
    </transcation> 
    <transcation ID="3"> 
     <BankName>ABC</BankName> 
     <TemplatModel>CT1</TemplatModel> 
     <Date>10/12/2014</Date> 
     <Payeename>pqr</Payeename> 
     <Amount>400</Amount> 
    </transcation> 
    <transcation ID="4"> 
     <BankName>EFG</BankName> 
     <TemplatModel>CT2</TemplatModel> 
     <Date>11/12/2014</Date> 
     <Payeename>asd</Payeename> 
     <Amount>300</Amount> 
    </transcation> 
</transactions> 

我需要找到量的總和,其中BANKNAME =「ABC」和在另一個查詢我需要找到量的其日期小於「二〇一四年十二月十二日」

和一種或多種其懷疑XML結構是更好

總和
<transactions> 
    <transcation ID="1" BankName="ABC" TemplatModel="CT1" Date="12/12/2014" Payeename="asd" Amount="200"/> 
    <transcation ID="2" BankName="EFG" TemplatModel="CT2" Date="12/12/2014" Payeename="xyz" Amount="100"/> 
    <transcation ID="3" BankName="ABC" TemplatModel="CT1" Date="10/12/2014" Payeename="pqr" Amount="400"/> 
    <transcation ID="4" BankName="EFG" TemplatModel="CT2" Date="11/12/2014" Payeename="asd" Amount="300"/> 
</transactions> 

編輯問題

我正在返回的查詢結果時,列出得到一個錯誤

public static List<string> banksearch(string bankname, string sdate = null, string edate = null, string condition = null) 
    { 
    } 

return transactions 
         .Where(t => t.BankName == bankname && t.Date == startdate) 
         .Select(t => new 
           { 
            TransactionID = t.TransactionID, 
            BankName = t.BankName, 
            TemplateModel = t.TemplateModel, 
            Date = t.Date, 
            PayeeName = t.PayeeName, 
            Amount = t.Amount 
           }).ToList(); 

我的錯誤是

Error 2 Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.List<string>' 

回答

2

我打算提供一個稍微不同的方法。在你的問題中,你提到了兩個查詢,我可以看到你需要其他查詢。在這種情況下,我建議將XML解析爲一個對象,並收集這些對象的集合,然後再查詢它們。

首先,對象(類),以保持所述數據事務:

public class Transaction 
{ 

    public int TransactionID { get; set; } 
    public string BankName { get; set; } 
    public string TemplatModel {get; set; } 
    public DateTime Date { get; set; } 
    public string PayeeName { get; set; } 
    public decimal Amount { get; set; } 
} 

注意,我選擇小數來表示量 - 這是貨幣單位正常的選擇。

接下來,你可以使用LINQ到XML的XML解析爲Transaction對象的集合,像這樣(根據你的第一個XML),並假設你有一個XDocument命名xDoc表示XML文件:

List<Transaction> transactions = xDoc.Root.Elements("transcation") 
     .Select(x => new Transaction() { 
         TransactionID = Convert.ToInt32((string)x.Attribute("ID")), 
         BankName = (string)x.Element("BankName"), 
         TemplatModel = (string)x.Element("TemplatModel"), 
         Date = Convert.ToDateTime((string)x.Element("Date")), 
         PayeeName = (string)x.Element("Payeename"), 
         Amount = Convert.ToDecimal((string)x.Element("Amount")) 
     }).ToList(); 

請注意使用(string) - 這將優雅地處理丟失的元素,而不會拋出空引用異常。

最後,您transactions集合,你可以運行任何你想要的類型的查詢,包括你在你的問題中提到的兩個:

var banksByName = transactions.Where(t => t.BankName == "ABC") 

而且

DateTime selectedDate = new DateTime(2014, 12, 22); 
var transByDate = transactions.Where(t => t.Date < selectedDate); 

這種方法的優點是您一次查詢XML以開發對象集合,然後可以根據需要隨時查詢該集合。

編輯補充修復了新的錯誤

你得到Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.List<string>'錯誤的原因是你方法需要返回List<string>,你實際上是返回一個List<AnonymousType>。當您在沒有具體類的LINQ Select語句中使用new關鍵字時,您創建的匿名類型不能在方法中返回。

爲了解決這個問題,你的方法的返回類型更改爲List<Transaction>new關鍵字後加上Transaction

public static List<Transaction> banksearch(string bankname, string sdate = null, string edate = null, string condition = null) 
{ 

    return transactions.Where(t => t.BankName == bankname && t.Date == startdate) 
         .Select(t => new Transaction() { 
           TransactionID = t.TransactionID, 
           BankName = t.BankName, 
           TemplateModel = t.TemplateModel, 
           Date = t.Date, 
           PayeeName = t.PayeeName, 
           Amount = t.Amount 
         }).ToList(); 
+0

你可能正在糾正他的錯誤,但我想我應該指出,用戶將他的元素拼寫爲「transcations」和「transcation」。 – furkle 2014-11-02 07:26:57

+0

@furkle - 謝謝,我沒注意到。我爲一家金融機構工作,所以我的思想自動閱讀「交易」。如果OP複製和粘貼,我更新了LINQ查詢。 – Tim 2014-11-02 07:30:06

+0

是的,我也很喜歡它。我想要糾正它,但像大多數情況一樣,必須要有一定程度的信任才能讓提問者知道他們在做什麼,並且可能的錯別字在要糾正的事情列表中似乎很低。 – furkle 2014-11-02 07:31:57

3

您可以使用LINQ到XML的這個:

DateTime exclusiveDateTime = new DateTime(2014, 12, 12); 

// instantiate and load your XDocument as yourXDocument here 

XElement transcationsElement = yourXDocument.Root; 

IEnumerable<int> amounts = from transcation in transcationsElement.Descendants("transcation") 
          where transcation.Attribute("BankName").Value == "ABC" && 
           Convert.ToDateTime(transcation.Attribute("Date").Value) < exclusiveDateTime 
          select Convert.ToDecimal(transcation.Attribute("amount")); 

decimal amountsSum = amounts.Sum(); 

我使用了你發佈的第二個XML表單,因爲我發現處理元素的相關屬性相對於元素的子元素更容易處理,但這主要是我個人偏好。此解決方案假定您的日期和金額屬性的每個分別適當形成DateTime字符串和整數。如果情況並非如此,您將遇到InvalidCastExceptions。注意 - 如果你想擴展你的XML,並且你需要在你的transcation元素上執行更多的查詢,你應該創建一個類來封裝每個元素中包含的數據,然後使用LINQ對象分析您的數據並實例化每個對象。

1

我會幫你與一個查詢(量的總和)和另一個查詢你自己嘗試基於第一查詢

int sum = 0; 
transactionXml.Descendants("transaction").ToList().ForEach(i => { 
    if (String.Equals(i.Element("BankName").Value, "abc", StringComparison.OrdinalIgnoreCase)) 
     sum += Convert.ToInt32(i.Element("Amount").Value); 
}); 

關於XML結構,銀行名稱,收款人名稱可以使用特殊字符,它可以打破你的xml。因此建議的XML結構如下

<transactions> 
    <transcation ID="1" TemplatModel="CT1" Date="12/12/2014" Amount="200"> 
     <BankName>ABC</BankName> 
     <Payeename>asd</Payeename> 
    </transcation> 
    *** 
    *** 
    *** 
</transactions> 
+0

最好能包住數據''和''在CDATA以避免特殊字符打破解析器。即,'<![CDATA [ABC]]>'或<'Payeename><![CDATA [asd]]>'。 – Tim 2014-11-02 07:45:22

+0

@Tim:是的,包裝CDATA會更安全。 – 2014-11-02 08:27:39

相關問題