我想使用linq从我的xml文档中获取数据(由于它是从外部程序生成的,我无法更改此XML)。出于某种原因,_dup_check_lvl
和_inv_doc_type
为空。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Xml.Linq;
namespace ETrans
{
public class Edata
{
List<Edata> invoice = new List<Edata>();
public string _dup_check_lvl { get; private set; }
public string _inv_doc_type { get; private set; }
public void get_invoice_data()
{
XDocument doc = XDocument.Load("test.xml");
var invoice_data = doc.Root
.Elements("Invoice")
.Select(x => new Edata
{
_inv_doc_type = (string)x.Attribute("Check_Level").Value,
_dup_check_lvl = (string)x.Attribute("Document_Type").Value
})
.ToList();
Console.WriteLine(_dup_check_lvl);
Console.WriteLine(_inv_doc_type);
}
}
}
<Invoice>
<Check_Level>2</Check_Level>
<Document_Type>RE</Document_Type>
<Invoice>
答案 0 :(得分:2)
这应该更好:
var invoice_data = doc.Elements("Invoice")
.Select(x => new Edata
{
_inv_doc_type = x.Element("Check_Level").Value,
_dup_check_lvl = x.Element("Document_Type").Value
})
.ToList();
Document_Type
和Check_Level
是元素,而不是属性。此外,这假设该文件将具有多个Invoice
元素,这将违反XML格式。
因此,考虑到XML文件只能有一个顶级元素,您真正想要的可能是这样的:
void Main()
{
var edata = new Edata();
edata.get_invoice_data();
Console.WriteLine(edata._dup_check_lvl);
Console.WriteLine(edata._inv_doc_type);
}
class Edata
{
public string _inv_doc_type { get; set; }
public string _dup_check_lvl { get; set; }
public void get_invoice_data()
{
// replace with reading from file.
var doc = XDocument.Parse(@"<Invoice>
<Check_Level> 2 </Check_Level>
<Document_Type> RE </Document_Type>
</Invoice> ");
var invoice_data = doc.Root; // or doc.Element("Invoice")
_inv_doc_type = invoice_data.Element("Check_Level").Value;
_dup_check_lvl = invoice_data.Element("Document_Type").Value;
}
}
答案 1 :(得分:1)
这并不是你认为它做的。
.Select(x => new Edata
{
_inv_doc_type = (string)x.Attribute("Check_Level").Value,
_dup_check_lvl = (string)x.Attribute("Document_Type").Value
})
不是在_inv_doc_type
的当前实例上设置_dup_check_lvl
和Edata
,而是创建并返回一个新的,不同的,不同的Edata
对象。
对于每个&#34;发票&#34;您在XML中找到的元素,它创建并返回一个Edata
实例。 Linq返回所有Edata
个对象的枚举(认为发生了,您的文件只创建一个)。然后,您在该枚举上调用ToList()
将其转换为List<Edata>
。最后一步并非绝对必要。
试试这个:
public void get_invoice_data()
{
XDocument doc = XDocument.Load("test.xml");
var invoice_data =
doc.Root
.Elements("Invoice")
.Select(x => new Edata
{
_inv_doc_type = (string)x.Attribute("Check_Level").Value,
_dup_check_lvl = (string)x.Attribute("Document_Type").Value
})
;
foreach (var edata in invoice_data) {
Console.WriteLine(edata._dup_check_lvl);
Console.WriteLine(edata._inv_doc_type);
}
}
如果您可以保证XML 总是最多包含一个&#34; Invoice&#34;,并且您希望当前的Edata
实例设置自己的字段单一&#34;发票&#34;,这样做:
if (invoice_data.Any()) {
_dup_check_lvl = invoice_data.First()._dup_check_lvl;
_inv_doc_type = invoice_data.First()._inv_doc_type;
}