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>
I have an example of code converter (XML to CSV) but it works without headlines "Company" and "JobDetails". I need this headlines, can you help me to improve this code?
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();
}
}
}
Possibly code don't work because visual thinks that "Company" and "JobDetails" it's different Tables. This is should look like this (In CSV of cours): Company JobDetails
It should be in one CSV file.
Output text:
Title,Commentary,Worker1,Worker2
Seph,blah-blah,Bill,Fill
JobNum,Detail1,Detail2
1,Sport,Physical
2,Mailman,pastoral
By using 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>
</xsl:text>
<xsl:apply-templates select="Company"/>
<xsl:text>JobNum,Detail1,Detail2</xsl:text>
<xsl:text>
</xsl:text>
<xsl:for-each select="JobDetails[*]">
<xsl:value-of select="concat(JobNum, ',', Detail1, ',', Detail2)"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match="Company">
<xsl:value-of select="concat(Title, ',', Commentary, ',', Worker1, ',', Worker2)"/>
<xsl:text>
</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);
}
}
Output
Title,Commentary,Worker1,Worker2
Seph,blah-blah,Bill,Fill
JobNum,Detail1,Detail2
1,Sport,Physical
2,Mailman,pastoral
Well, using XSLT for the xml to csv transformation is one way to do it. Here is one another approach using Cinchoo ETL , an open source library to perform the transformation in native way
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);
Output:
Title,Commentary,Worker1,Worker2
Seph,blah-blah,Bill,Fill
JobNum,Detail1,Detail2
1,Sport,Physical
2,Mailman,pastoral
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.