Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用linq从我的xml c中获取数据_C#_Xml_Linq - Fatal编程技术网

C# 使用linq从我的xml c中获取数据

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 })

我想使用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 
}) 
它不在当前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谢谢你为我指明了正确的方向@埃德·普朗基特