C# 使用linq从我的xml c中获取数据
我想使用linq从我的xml文档中获取数据。我无法更改此xml,因为它是由外部程序生成的。由于某种原因,重复检查和库存单据类型为空 密码 我的xml文档C# 使用linq从我的xml c中获取数据,c#,xml,linq,C#,Xml,Linq,我想使用linq从我的xml文档中获取数据。我无法更改此xml,因为它是由外部程序生成的。由于某种原因,重复检查和库存单据类型为空 密码 我的xml文档 这和你想象的不一样 .Select(x => new Edata { _inv_doc_type = (string)x.Attribute("Check_Level").Value, _dup_check_lvl = (string)x.Attribute("Document_Type").Value })
这和你想象的不一样
.Select(x => new Edata
{
_inv_doc_type = (string)x.Attribute("Check_Level").Value,
_dup_check_lvl = (string)x.Attribute("Document_Type").Value
})
它不在当前Edata实例上设置_inv_doc_type和_dup_check_lvl,而是创建并返回一个新的、不同的、不同的Edata对象
对于XML中找到的每个Invoice元素,它创建并返回一个Edata实例。Linq返回所有这些Edata对象的枚举,您的文件只创建一个。然后调用该枚举上的ToList将其转换为列表。这最后一步并不是绝对必要的
试试这个:
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始终最多包含一张发票,并且希望当前的Edata实例根据该发票设置自己的字段,则可以执行以下操作:
if (invoice_data.Any()) {
_dup_check_lvl = invoice_data.First()._dup_check_lvl;
_inv_doc_type = invoice_data.First()._inv_doc_type;
}
这和你想象的不一样
.Select(x => new Edata
{
_inv_doc_type = (string)x.Attribute("Check_Level").Value,
_dup_check_lvl = (string)x.Attribute("Document_Type").Value
})
它不在当前Edata实例上设置_inv_doc_type和_dup_check_lvl,而是创建并返回一个新的、不同的、不同的Edata对象
对于XML中找到的每个Invoice元素,它创建并返回一个Edata实例。Linq返回所有这些Edata对象的枚举,您的文件只创建一个。然后调用该枚举上的ToList将其转换为列表。这最后一步并不是绝对必要的
试试这个:
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始终最多包含一张发票,并且希望当前的Edata实例根据该发票设置自己的字段,则可以执行以下操作:
if (invoice_data.Any()) {
_dup_check_lvl = invoice_data.First()._dup_check_lvl;
_inv_doc_type = invoice_data.First()._inv_doc_type;
}
这应该更好地发挥作用:
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();
文档类型和检查级别是元素,而不是属性。此外,这假设文件将有多个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;
}
}
这应该更好地发挥作用:
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();
文档类型和检查级别是元素,而不是属性。此外,这假设文件将有多个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;
}
}
太棒了,谢谢你给我指出了正确的方向@Ed PlunkettAwesome谢谢你为我指明了正确的方向@埃德·普朗基特