首页 > 解决方案 > 使用 LINQ 和 XELEMENT 从 CSV 创建 XML

问题描述

我必须从 csv 文件创建一个 xml 文件。实际上我使用这段代码:

XElement header = new XElement("header",
    from str in source
    let fields = str.Split('|')
    select new XElement("Header",
        //new XAttribute("CustomerID", fields[0]),
        new XElement("FileId", fields[1]),//da calcolare
        new XElement("SenderId", fields[2]),
        new XElement("ProcessingDate", DateTime.Now.ToString("yyyyMMdd")),
        new XElement("ProcessingTime", DateTime.Now.ToString("HHmm"))
        )
    );

这将创建 2 个标签:"header xmlns="""Header; 我怎样才能只创建一个标签“标题”?

输出:

<header xmlns="">
 <Header>
 <FileId>00476170246</FileId>
 <SenderId>TEST</SenderId>
 <ProcessingDate>20210819</ProcessingDate>
 <ProcessingTime>1825</ProcessingTime>
 </Header>
</header>

标签: c#xmllinq

解决方案


LINQ 用于处理集合。

如果您只想创建一个元素,那么按照您的方式使用 Linq 是没有意义的。

你在你的代码中做了什么:

您使用 手动创建一个 Header 元素new XElement(..),然后让 LINQ 用source集合中尽可能多的标题填充该元素,方法是告诉它from每个源它应该拆分文本,然后select是一个新的 Header。

所以,这就是为什么结果看起来和你描述的完全一样:

<YOUR Header (from new)>
  <LINQ CREATED HEADER (from select new(...))
  [<LINQ CREATED HEADER (from select new(...), when source has more entries)]
  [<LINQ CREATED HEADER (from select new(...), when source has more entries))]
</YOUR Header>

看那个:

https://dotnetfiddle.net/f2Uo8Y

using System.Collections.Generic;
using System;
using System.Linq;
using System.Xml.Linq;
using Newtonsoft.Json;
                    
public class Program
{
    public static void Main()
    {
        var source = new List<string>();
        source.Add("fid|sid|pd|pt");
        
        //2. comment this in and see 
        //source.Add("fid2|sid2|pd2|pt2");
        
        //1. when you do a FROM, you receive collections back, not single objects
        var headerElements = from str in source
            let fields = str.Split('|')
            select new XElement("Header",
                new XElement("FileId", fields[1]),//da calcolare
                new XElement("SenderId", fields[2]),
                new XElement("ProcessingDate", DateTime.Now.ToString("yyyyMMdd")),
                new XElement("ProcessingTime", DateTime.Now.ToString("HHmm"))
        );
    
        Console.WriteLine(JsonConvert.SerializeObject(headerElements));
    
        //now, if you want only one element, you could assume that source has only one entry, and crop the result 
        var headerElement = headerElements.FirstOrDefault();
        Console.WriteLine(JsonConvert.SerializeObject(headerElement));
    
        //BUT: in that case, solving that via LINQ makes absolutely no sense
    }
}

推荐阅读