簡體   English   中英

在 C# 中不使用 CsvHelper 將 XML 解析為 CSV

[英]Parse XML to CSV without CsvHelper in C#

我正在嘗試將 XML 文件轉換為 CSV 但我正在運行的 .NET 版本不支持這里似乎很流行的 CsvHelper 庫。

XML 文檔簡化如下:

<E1AFKOL SEGMENT="1">
    <MATNR>456654546</MATNR>
    <E1AFFLL SEGMENT="1">
        <APLZL>00000001</APLZL>
        <E1AFVOL SEGMENT="1">
            <VORNR>0020</VORNR>
            <E1RESBL SEGMENT="1">
                <AUSCH>0.00</AUSCH>
            </E1RESBL>
            <E1RESBL SEGMENT="1">
                <AUSCH>0.00</AUSCH>
                <BDART>AR</BDART>
                <BDMNG>1.000</BDMNG>
                <BDTER>20190626</BDTER>
                <MATNR>LD1000345</MATNR>
                <MEINS>EA</MEINS>
                <VMENG>1.000</VMENG>
                <WERKS>1110</WERKS>
            </E1RESBL>
        </E1AFVOL>
    </E1AFFLL>
</E1AFKOL>

我只需要第 0 列中的MATNR標簽(主鍵) 。E1RESBL標簽的內容是需要添加的值(第 1-6 列),但並非結構中的所有標簽都需要。

我將 XML 文檔作為 XElement 和列名列表傳遞。 它返回一個列表中的所有值。

public static List<string> makeRows(XElement xmlD, List<string> columnNames) {
    List<string> columnNames = new List<string>();
    string[] wkOrdColumnNames = { "AUFNR", "AUSCH", "BDMNG", "BDTER", "MATNR", "MEINS", "WERKS" };   // all other fields needed
    columnNames.AddRange(wkOrdColumnNames); // adds the others
    // Load each structure
    var E1RESBL = xmlD.XPathSelectElements(@"/IDOC/E1AFKOL/E1AFFLL/E1AFVOL/E1RESBL");  // XML structure within doc
    var E1AFKOL = xmlD.XPathSelectElements(@"/IDOC/E1AFKOL");                     // column0 structure

    List<string> tagValues = new List<string>(); // all values from the tags are stored here
    // Where the WorkOrderID is added to the the values
    foreach (var innerNode in E1AFKOL) {                        // loops through the parent structure
        foreach (var innerElement in innerNode.XPathSelectElements(columnNames[0]))        // passes the element(AUFNR), gets the value of that tag
            tagValues.Add(innerElement.Value);            // adds it to the List
    }
    // The rest of the fields are added here
    foreach (var innerNode in E1RESBL) {                // loops through all tags in E1RESBL structure
        foreach (string i in columnNames) {            // loops through each string in the array of column names
            foreach (var innerElement in innerNode.XPathSelectElements(i))
                tagValues.Add(innerElement.Value);
        }
    }
    return tagValues;
}

然后,我將列名和值傳遞給 DataTable。

public static DataTable makeDataTable(List<string> columns, List<string> rows) {
    // Make Data table
    DataTable dataT = new DataTable();
    DataColumn dCol = new DataColumn();
    // Add columns
    foreach (var i in columns) {
        dCol.DataType = Type.GetType("System.String");
        dCol.ColumnName = i;
        dataT.Columns.Add(dCol.ColumnName, dCol.DataType);
    }
    // Add rows
    dataT.Rows.Add(rows[0]); // adds to column 0
    for (int r = 1; r < (rows.Capacity-1); r++) {   // starts after the 0th element (wkOrdID)
        DataRow dr = dataT.NewRow();            // Adds a new row
        Console.WriteLine(rows[r]);
        for (int j = 1; j < 7; j++) {           // skips the 0th column
            dr[j] = rows[r];                    // adds the values of the list to the row
        }
        dataT.Rows.Add(dr);
    }

我知道可能有一種更簡單的方法可以做到這一點,所以如果你能提供幫助,將不勝感激。

成品示例

試試下面的代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
using System.IO;

namespace ConsoleApplication142
{
    class Program
    {
        const string XML_FILENAME = @"c:\temp\test.xml";
        const string CSV_FILENAME = @"c:\temp\test.csv";
        static void Main(string[] args) 
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("E1AFKOL SEGMENT", typeof(int));
            dt.Columns.Add("E1AFKOL MATNR", typeof(long));
            dt.Columns.Add("E1AFFLL SEGMENT", typeof(int));
            dt.Columns.Add("APLZL", typeof(string));
            dt.Columns.Add("E1AFVOL SEGMENT", typeof(int));
            dt.Columns.Add("VORNR", typeof(string));
            dt.Columns.Add("E1RESBL SEGMENT", typeof(int));
            dt.Columns.Add("AUSCH", typeof(decimal));
            dt.Columns.Add("BDART", typeof(string));
            dt.Columns.Add("BDMNG", typeof(decimal));
            dt.Columns.Add("BDTER", typeof(long));
            dt.Columns.Add("E1RESBL MATNR", typeof(string));
            dt.Columns.Add("MEINS", typeof(string));
            dt.Columns.Add("VMENG", typeof(decimal));
            dt.Columns.Add("WERKS", typeof(int));

            XDocument doc = XDocument.Load(XML_FILENAME);

            foreach (XElement E1AFKOL in doc.Descendants("E1AFKOL"))
            {
                int E1AFKOL_SEGMENT = (int)E1AFKOL.Attribute("SEGMENT");
                long E1AFKOL_MATNR = (long)E1AFKOL.Element("MATNR");

                foreach (XElement E1AFFLL in E1AFKOL.Elements("E1AFFLL"))
                {
                    int E1AFFLL_SEGMENT = (int)E1AFFLL.Attribute("SEGMENT");
                    string APLZL = (string)E1AFFLL.Element("APLZL");

                    foreach (XElement E1AFVOL in E1AFFLL.Elements("E1AFVOL"))
                    {
                        int E1AFVOL_SEGMENT = (int)E1AFVOL.Attribute("SEGMENT");
                        string VORNR = (string)E1AFVOL.Element("VORNR");

                        foreach (XElement E1RESBL in E1AFVOL.Elements("E1RESBL"))
                        {
                            int E1RESBL_SEGMENT = (int)E1RESBL.Attribute("SEGMENT");
                            decimal? AUSCH = (decimal?)E1RESBL.Element("AUSCH");
                            string BDART = (string)E1RESBL.Element("BDART");
                            decimal? BDMNG = (decimal?)E1RESBL.Element("BDMNG");
                            long? BDTER = (long?)E1RESBL.Element("BDTER");
                            string E1RESBL_MATNR = (string)E1RESBL.Element("MATNR");
                            string MEINS = (string)E1RESBL.Element("MEINS");
                            decimal? VMENG = (decimal?)E1RESBL.Element("VMENG");
                            int? WERKS = (int?)E1RESBL.Element("WERKS");

                            dt.Rows.Add(new object[] {
                                E1AFKOL_SEGMENT,
                                E1AFKOL_MATNR,
                                E1AFFLL_SEGMENT,
                                APLZL,
                                E1AFVOL_SEGMENT,
                                VORNR,
                                E1RESBL_SEGMENT,
                                AUSCH,
                                BDART,
                                BDMNG,
                                BDTER,
                                E1RESBL_MATNR,
                                MEINS,
                                VMENG,
                                WERKS 
                            });

                        }
                    }
                }
            }

            StreamWriter writer = new StreamWriter(CSV_FILENAME);
            string header = string.Join(",", dt.Columns.Cast<DataColumn>().Select(x => x.ColumnName));
            writer.WriteLine(header);

            foreach (DataRow row in dt.AsEnumerable())
            {
                string rowStr = string.Join(",", row.ItemArray.Select(x => x.ToString()));
                writer.WriteLine(rowStr);
            }
            writer.Flush();
            writer.Close();


        }
    }



}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM