【问题标题】:Looping through an XML file to store in to a CSV using C#使用 C# 循环通过 XML 文件存储到 CSV
【发布时间】:2017-12-12 15:03:00
【问题描述】:

在我的项目中,我使用了一个时间日志 API,其中包括一个长 XML 文件,其中包括员工 ID、姓名、公司名称、ID 等。现在我想将该 XML 属性存储到一个带有该属性名称标题的 CSV 文件中。例如员工姓名、员工 ID 等。使用我的代码,XML 文件的循环现在正在工作。它会给出所有错误消息,有时会多次给出一个值。

我的项目的 XML 文件

     <?xml version="1.0" encoding="utf-8"?>
<tlp:WorkUnits xmlns:tlp="http://www.timelog.com/XML/Schema/tlp/v4_4"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.timelog.com/XML/Schema/tlp/v4_4 http://www.timelog.com/api/xsd/WorkUnitsRaw.xsd">
  <tlp:WorkUnit ID="130">
    <tlp:EmployeeID>3</tlp:EmployeeID>
    <tlp:AllocationID>114</tlp:AllocationID>
    <tlp:TaskID>239</tlp:TaskID>
    <tlp:ProjectID>26</tlp:ProjectID>
    <tlp:ProjectName>LIK Template</tlp:ProjectName>  
  </tlp:WorkUnit>

我有一个工作单元类,其中我为 XML 声明了属性。

现在我创建了一个类,我想在其中循环遍历 XML 并将该文件存储到 CSV 中,但没有正确显示。

这是那个类

    namespace TimeLog.ApiConsoleApp
{
    /// <summary>
    /// Template class for consuming the reporting API
    /// </summary>
    public class ConsumeReportingApi
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(ConsumeReportingApi));

        public static void Consume()
        {
            if (ServiceHandler.Instance.TryAuthenticate())
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info("Successfully authenticated on reporting API");
                }

                var customersRaw = ServiceHandler.Instance.Client.GetWorkUnitsRaw(ServiceHandler.Instance.SiteCode,
                     ServiceHandler.Instance.ApiId,
                     ServiceHandler.Instance.ApiPassword,

                  );



                if (customersRaw.OwnerDocument != null)
                {
                     var namespaceManager = new XmlNamespaceManager(customersRaw.OwnerDocument.NameTable);
                namespaceManager.AddNamespace("tlp", "http://www.timelog.com/XML/Schema/tlp/v4_4");
                var workUnit = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);


                    if (workUnit != null)
                    {
                        var output = new StringBuilder();
                        foreach (XmlNode customer in workUnit)
                        {
                            var unit = new WorkUnit();
                            var childNodes = customer.SelectNodes("./*");

                            if (childNodes != null)
                            {
                                foreach (XmlNode childNode in childNodes)
                                {
                                    if (childNode.Name == "tlp:EmployeeID")
                                    {

                                        unit.EmployeeID = Int32.Parse(childNode.InnerText);
                                     }
                                    if (childNode.Name == "tlp:EmployeeFirstName")
                                    {
                                        unit.ProjectName = childNode.InnerText;
                                    }
                                    if (childNode.Name == "tlp:EmployeeLastName")
                                    {
                                        unit.ProjectName = childNode.InnerText;
                                    }

                                    if (childNode.Name == "tlp:AllocationID")
                                    {
                                        unit.ProjectName = childNode.InnerText;
                                    }

                                    if (childNode.Name == "tlp:TaskName")
                                    {
                                        unit.ProjectName = childNode.InnerText;
                                    }

                                }



                            output.AppendLine($"{unit.EmployeeID},{unit.EmployeeFirstName},{unit.EmployeeLastName},{unit.AllocationID},{unit.TaskName}");

                            }

                            Console.WriteLine(output.AppendLine($"{unit.EmployeeID},{unit.EmployeeFirstName},{unit.EmployeeLastName},{unit.AllocationID},{unit.TaskName}"));

                        }
                    }
                }

                else
                {
                    if (Logger.IsWarnEnabled)
                    {
                        Logger.Warn("Failed to authenticate to reporting API");
                    }
                }
            }
        }
    }
}

我的输出文件如下所示

    387,,,-1,

387,,,-1,
388,,,-1,

387,,,-1,
388,,,-1,
388,,,-1,

387,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,

387,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,

387,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,

387,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
410,,,-1,

387,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
388,,,-1,
410,,,-1,
447,,,-1,

【问题讨论】:

    标签: c# xml csv


    【解决方案1】:

    在每次迭代中将childNode.InnerText 附加到StringBuilder

    var workUnit = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
    if (workUnit != null)
    {
        var output = new StringBuilder();
        foreach (XmlNode customer in workUnit)
        {
            //var unit = new WorkUnit();
            var childNodes = customer.SelectNodes("./*");
            if (childNodes != null)
            {
                for (int i = 0; i<childNodes.Count; ++i)
                {
                    XmlNode childNode = childNodes[i];
                    /*if (childNode.Name == "tlp:EmployeeID")
                    {
                        unit.EmployeeID = Int32.Parse(childNode.InnerText);
                    }
                    if (childNode.Name == "tlp:EmployeeFirstName")
                    {
                        unit.ProjectName = childNode.InnerText;
                    }
                    if (childNode.Name == "tlp:EmployeeLastName")
                    {
                        unit.ProjectName = childNode.InnerText;
                    }
    
                    if (childNode.Name == "tlp:AllocationID")
                    {
                        unit.ProjectName = childNode.InnerText;
                    }
    
                    if (childNode.Name == "tlp:TaskName")
                    {
                        unit.ProjectName = childNode.InnerText;
                    }*/
                    output.Append(childNode.InnerText);
                    if(i<childNodes.Count - 1)
                        output.Append(",");
                }
                output.Append(Environment.NewLine);
            }
        }
    }
    

    【讨论】:

    • @tamrezh21:你试过这个吗?您似乎是根据您在最新问题中发布的代码所做的。如果您的问题已解决,请记住接受答案并投票。
    【解决方案2】:

    试试 xml linq:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    using System.IO;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string XML_FILENAME = @"c:\temp\test.xml";
            const string CSV_FILENAME = @"c:\temp\test.csv";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(XML_FILENAME);
                StreamWriter writer = new StreamWriter(CSV_FILENAME);
    
                XElement firstWorkUnit = doc.Descendants().Where(x => x.Name.LocalName == "WorkUnit").FirstOrDefault();
                XNamespace ns = firstWorkUnit.GetNamespaceOfPrefix("tlp");
    
    
                List<XElement> workUnits = doc.Descendants(ns + "WorkUnit").ToList();
                foreach (XElement workUnit in workUnits)
                {
                    string outputline = string.Join(",", new string[] {
                        (string)workUnit.Element(ns + "EmployeeID"),
                        (string)workUnit.Element(ns + "AllocationID"),
                        (string)workUnit.Element(ns + "TaskID"),
                        (string)workUnit.Element(ns + "ProjectID"),
                        (string)workUnit.Element(ns + "ProjectName"),
                        (string)workUnit.Element(ns + "CustomerId"),
                        (string)workUnit.Element(ns + "CustomerName"),
                        (string)workUnit.Element(ns + "IsBillable"),
                        (string)workUnit.Element(ns + "ApprovedStatus"),
                        (string)workUnit.Element(ns + "LastModifiedBy")
                    });
    
                    writer.WriteLine(outputline);
                }
    
                writer.Flush();
                writer.Close();
            }
        }
    }
    

    【讨论】:

    • @jdweng我有来自我提供的网络链接的 xml。谢谢你。但是您的解决方案与我的代码完全不同。如何更正我的代码以获得正确的值
    • 我认为您的代码缺少命名空间,建议您使用我的代码更高效。
    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-04-27
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多