IEnumerable in LINQ 只有一个节点实例时
IEnumerable in LINQ when only one instance of the node
我正在尝试使用 Linq 查询一些 XML。我有以下 XML ...
的片段
<report>
<invoice>
<id>A4245</id>
<date>12-20-2016</date>
<amount>12.50</amount>
</invoice>
<report>
这是我保存数据的模型
public class InvoiceModel
{
public string InvoiceId { get; set; }
public string InvoiceDate { get; set; }
public string InvoiceAmount { get; set; }
}
这是 LINQ 查询
XDocument xml = XDocument.Parse(@"C:\Path\To\data.xml");
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel
{
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
});
我得到的错误是..
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<InvoiceModel>' to 'InvoiceModel'. An explicit conversion exists (are you missing a cast?)
XML 中只会有一张发票。我如何告诉 LINQ 查询只有一个发票实例并且不需要 IEnumerable
?
P.S。我将所有字符串都用于 属性 值,因为它们只是用作文本,不会被解析。
尝试
XDocument xml = XDocument.Parse(@"C:\Path\To\data.xml");
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel
{
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
}).FirstOrDefault();
发生这种情况是因为 Descendants(...)
returns 一个 IEnumerable<T>
,然后用 Select
转换为 IEnumerable<InvoiceModel>
。如果你知道最多有一个后代具有正确的名字,使用 FistsOrDefault()
检索它:
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel {
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
}).FirstOrDefault();
// Make sure that you get an invoice
if (invoice == null) {
throw new InvalidOperationException("Invoice element does not exist in XML document.");
}
您可以使用 .FirstOrDefault()
到 select 唯一的 invoice
元素:
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel
{
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
})
.FirstOrDefault();
您的代码中还有其他问题:
- 您想使用
XDocument.Load
加载文件,Parse
用于原始 xml。
- xml 未正确终止。最后一个标签应该是
</report>
.
.Select()
returns一个合集。如果该集合中只有一个元素,则追加:
.Single()
如果可以有多个而你想要第一个:
.First()
如果应该有但可能是 none:
.SingleOrDefault()
等等
您可以应用多种逻辑,任何 IEnumerable<T>
都有多种扩展方法。基本上,如果您只想要一个,select 就是 .Select()
.
返回的集合中的那个
我正在尝试使用 Linq 查询一些 XML。我有以下 XML ...
的片段<report>
<invoice>
<id>A4245</id>
<date>12-20-2016</date>
<amount>12.50</amount>
</invoice>
<report>
这是我保存数据的模型
public class InvoiceModel
{
public string InvoiceId { get; set; }
public string InvoiceDate { get; set; }
public string InvoiceAmount { get; set; }
}
这是 LINQ 查询
XDocument xml = XDocument.Parse(@"C:\Path\To\data.xml");
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel
{
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
});
我得到的错误是..
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<InvoiceModel>' to 'InvoiceModel'. An explicit conversion exists (are you missing a cast?)
XML 中只会有一张发票。我如何告诉 LINQ 查询只有一个发票实例并且不需要 IEnumerable
?
P.S。我将所有字符串都用于 属性 值,因为它们只是用作文本,不会被解析。
尝试
XDocument xml = XDocument.Parse(@"C:\Path\To\data.xml");
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel
{
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
}).FirstOrDefault();
发生这种情况是因为 Descendants(...)
returns 一个 IEnumerable<T>
,然后用 Select
转换为 IEnumerable<InvoiceModel>
。如果你知道最多有一个后代具有正确的名字,使用 FistsOrDefault()
检索它:
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel {
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
}).FirstOrDefault();
// Make sure that you get an invoice
if (invoice == null) {
throw new InvalidOperationException("Invoice element does not exist in XML document.");
}
您可以使用 .FirstOrDefault()
到 select 唯一的 invoice
元素:
InvoiceModel invoice = xml.Descendants("invoice")
.Select(x => new InvoiceModel
{
InvoiceId = x.Element("id").Value.ToString(),
InvoiceDate = x.Element("date").Value.ToString(),
InvoiceAmount = x.Element("amount").Value.ToString()
})
.FirstOrDefault();
您的代码中还有其他问题:
- 您想使用
XDocument.Load
加载文件,Parse
用于原始 xml。 - xml 未正确终止。最后一个标签应该是
</report>
.
.Select()
returns一个合集。如果该集合中只有一个元素,则追加:
.Single()
如果可以有多个而你想要第一个:
.First()
如果应该有但可能是 none:
.SingleOrDefault()
等等
您可以应用多种逻辑,任何 IEnumerable<T>
都有多种扩展方法。基本上,如果您只想要一个,select 就是 .Select()
.