我需要根据某些标准总结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”的金额总和,在另一个查询中,我需要查找日期小于“12/12/2014”的金额总和
还有一个人怀疑哪个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>
编辑问题
将查询结果返回到List
时出错 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>'
答案 0 :(得分:3)
您可以使用LINQ to 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表单,因为我发现处理元素的相关属性比元素的子元素更容易,但这主要是个人偏好。此解决方案假定您的Date和Amount属性中的每一个都分别正确地形成为DateTime字符串和整数。如果不是这种情况,你会遇到InvalidCastExceptions。
注意 - 如果您正在考虑扩展XML,并且需要对transcation
元素执行更多查询,则应该创建一个类来封装每个元素中包含的数据,并且使用LINQ to Objects来解析数据并实例化每个对象。
答案 1 :(得分: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 to XML将XML解析为Transaction
个对象的集合,就像这样(基于您的第一个XML),假设您有一个名为{{1}的XDocument
表示XML文件:
xDoc
请注意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")
这种方法的优点是您可以一次查询XML以开发对象集合,然后您可以根据需要经常查询该集合。
已修改为新错误添加修补程序
您收到DateTime selectedDate = new DateTime(2014, 12, 22);
var transByDate = transactions.Where(t => t.Date < selectedDate);
错误的原因是您的方法预计会返回Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.List<string>'
,并且您实际上正在返回List<string>
。如果在没有具体类的LINQ Select语句中使用List<AnonymousType>
关键字,则需要创建一个匿名类型,该类型不能在方法中返回。
要解决此问题,请将方法的返回类型更改为new
,并在List<Transaction>
关键字后添加Transaction
:
new
答案 2 :(得分: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>