如何将 XML 转换为 CSV (C#)

Posted

技术标签:

【中文标题】如何将 XML 转换为 CSV (C#)【英文标题】:How to convert XML to CSV (C#) 【发布时间】:2021-04-29 12:25:44 【问题描述】:

XML:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <Company>
    <Title>Seph</Title>
    <Commentary>blah-blah</Commentary>
    <Worker1>Bill</Worker1>
    <Worker2>Fill</Worker2>
  </Company>
  <JobDetails>
    <JobNum>1</JobNum>
    <Detail1>Sport</Detail1>
    <Detail2>Physical</Detail2>
  </JobDetails>
  <JobDetails>
    <JobNum>2</JobNum>
    <Detail1>Mailman</Detail1>
    <Detail2>pastoral</Detail2>
  </JobDetails>
  <JobDetails />
</NewDataSet>

我有一个代码转换器(XML 到 CSV)的示例,但它可以在没有标题“公司”和“工作详情”的情况下工作。我需要这个标题,你能帮我改进这个代码吗?

using System;
using System.Text;
using System.IO;
using System.Xml.Linq;
using System.Linq;
namespace XML_CSV

    class Class1
    
        static void Main()
        
            StringBuilder sb = new StringBuilder();
            string delimiter = "|";

            XDocument.Load(@"C:\Users\Iuser\Desktop\Data.xml").Descendants("NewDataSet").ToList().ForEach(element => sb.Append(
                            element.Element("Company").Value + delimiter +  //something maybe bad here
                            element.Element("Title").Value + delimiter +
                            element.Element("Commentary").Value + delimiter +
                            element.Element("Worker1").Value + delimiter +
                            element.Element("Worker2").Value + delimiter +
                             element.Element("JobDetails").Value + delimiter + //something maybe bad here
                             element.Element("Detail1").Value + delimiter +
                             element.Element("Detail2").Value + "\r\n"));
            StreamWriter sw = new StreamWriter(@"C:\Users\Iuser\Desktop\DataCSV.csv");
            sw.WriteLine(sb.ToString());
            sw.Close();

        
    

可能代码不起作用,因为视觉认为“Company”和“JobDetails”是不同的表。 这应该看起来像这样(在 CSV 中): Company JobDetails

它应该在一个 CSV 文件中。

输出文本:

Title,Commentary,Worker1,Worker2
Seph,blah-blah,Bill,Fill
JobNum,Detail1,Detail2
1,Sport,Physical
2,Mailman,pastoral

【问题讨论】:

你能举一些例子说明输出的样子,以及你认为它应该是什么样的吗? 我添加了输出示例; 请编辑您的帖子并将所需的输出添加为文本。 如何使用 XSLT? 请澄清您的输出。它只有一行吗? 【参考方案1】:

通过使用 XSLT。

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/NewDataSet">
        <xsl:text>Title,Commentary,Worker1,Worker2</xsl:text>
        <xsl:text>&#xA;</xsl:text>
        <xsl:apply-templates select="Company"/>
        <xsl:text>JobNum,Detail1,Detail2</xsl:text>
        <xsl:text>&#xA;</xsl:text>
        <xsl:for-each select="JobDetails[*]">
            <xsl:value-of select="concat(JobNum, ',', Detail1, ',', Detail2)"/>
            <xsl:text>&#xA;</xsl:text>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="Company">
        <xsl:value-of select="concat(Title, ',', Commentary, ',', Worker1, ',', Worker2)"/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>
</xsl:stylesheet>

c#

void Main()

    const string SOURCEXMLFILE = @"e:\Temp\XML_to_CSV\input.xml";
    const string XSLTFILE = @"e:\Temp\XML_to_CSV\process.xslt";
    const string OUTPUTFILE = @"e:\Temp\XML_to_CSV\output.csv";

    try
    
        XsltArgumentList xslArg = new XsltArgumentList();

        using (XmlReader src = XmlReader.Create(SOURCEXMLFILE))
        
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(XSLTFILE, new XsltSettings(true, true), new XmlUrlResolver());

            XmlWriterSettings settings = xslt.OutputSettings.Clone();
            settings.IndentChars = "\t";
            // to remove BOM
            settings.Encoding = new UTF8Encoding(false);

            using (XmlWriter result = XmlWriter.Create(OUTPUTFILE, settings))
            
                xslt.Transform(src, xslArg, result, new XmlUrlResolver());
                result.Close();
            
        
        Console.WriteLine("File '0' has been generated.", OUTPUTFILE);
    
    catch (Exception ex)
    
        Console.WriteLine(ex.Message);
    

输出

Title,Commentary,Worker1,Worker2
Seph,blah-blah,Bill,Fill
JobNum,Detail1,Detail2
1,Sport,Physical
2,Mailman,pastoral

【讨论】:

谢谢!我有一个问题 - 将输出保存在 txt 文件中还是如何放置输出目标? 我更新了答案并添加了 c# 代码来执行 XSLT 转换。它是通用的,您可以将它应用于任何 XSLT。【参考方案2】:

嗯,使用 XSLT 进行 xml 到 csv 的转换是一种方法。这是使用Cinchoo ETL 的另一种方法,这是一个以本地方式执行转换的开源库

StringBuilder csv1 = new StringBuilder();
using (var r = new ChoXmlReader("XmlFile3.xml")
    .WithXPath("/Company")
    )

    using (var w = new ChoCSVWriter(csv1)
        .WithFirstLineHeader()
        .UseNestedKeyFormat(false)
        )
        w.Write(r);


StringBuilder csv2 = new StringBuilder();
using (var r = new ChoXmlReader("XmlFile3.xml")
    .WithXPath("/JobDetails")
    )

    using (var w = new ChoCSVWriter(csv2)
        .WithFirstLineHeader()
        .UseNestedKeyFormat(false)
        )
        w.Write(r);


string combinedCSV = csv1.ToString() + Environment.NewLine + csv2.ToString();

Console.WriteLine(combinedCSV);

输出:

Title,Commentary,Worker1,Worker2
Seph,blah-blah,Bill,Fill
JobNum,Detail1,Detail2
1,Sport,Physical
2,Mailman,pastoral

【讨论】:

以上是关于如何将 XML 转换为 CSV (C#)的主要内容,如果未能解决你的问题,请参考以下文章

在c#中将XML文件转换为csv文件格式

C# 如何将 CSV 转换为数组?

如何编写 XSLT 将 XML 转换为 CSV?

如何使用 XSL 将 XML 转换为 CSV

如何使用 XSL 将 liquibase XML 转换为 CSV

如何用C#将Excel转换成XML文件,希望把一些关键的地方讲得详细些,能让我明白就给分