加载XML文件并将其重写为CSV的正确方法是什么?

时间:2010-05-05 04:55:49

标签: c# xml csv linq-to-xml

更新为明确。

第一步:我有一个XML文件,我想加载到DatGridView中。 (主要是感谢Max,但我仍然遇到XML汇总问题)

第二步:根据用户输入运行一些代码 - (不是此解决方案的一部分)

第三步:将DataGridView导出为CSV文件。 (由Max解决!感谢Man这就是我在那部分尝试做的事情。)

使用VS 2008 C#

(创建一个新项目)

来自XML文件cars.xml的示例

<?xml version="1.0" encoding="utf-8" ?>
<root>
  <car>
    <year>2010</year>
    <make>Chevy</make>
    <model>Surburban</model>
    <color-e>Black</color-e>
    <color-i>Black</color-i>
    <features>
      <Engine>8 cylinder</Engine>
      <gas>Petrol</gas>
      <doors>5</doors>
      <miles>12312</miles>
    </features>
    </car>
  <car>
    <year>2001</year>
    <make>Ford</make>
    <model>Excursion</model>
    <color-e>Black</color-e>
    <color-i>Black</color-i>
    <features>
      <Engine>10 cylinder</Engine>
      <gas>Petrol</gas>
      <doors>5</doors>
      <miles>90312</miles>
    </features>
  </car>
  <car>
    <year>1999</year>
    <make>Chevy</make>
    <model>corvette</model>
    <color-e>Silver</color-e>
    <color-i>Black</color-i>
    <features>
      <Engine>8 cylinder</Engine>
      <gas>Petrol</gas>
      <doors>3</doors>
      <miles>44222</miles>
    </features>
  </car>
</root>

这是一个winform应用程序。 它有两个按钮,一个文本框和一个datagridview。 button one应该将XML数据加载到datagrid中。 然后按钮2应该将datagridview中的数据保存为CSV文件。

这是我到目前为止打开并将xml加载到datagridview中的代码。

namespace carsXML
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
        var cars = XDocument.Load(@"C:\cars.xml");
        var query = from c in cars.Descendants("car")
                    select new
                    {
                        Year = (string)c.Element("year").Value,
                        Make = (string)c.Element("make").Value,
                        Model = (string)c.Element("model").Value,
                        // I needed to step directly into the sub element.
                        gas = (string)c.Element("features").Element("gas").Value,
                        doors = (string)c.Element("features").Element("doors").Value,
                        miles = (string)c.Element("features").Element("miles").Value


                    };

        dataGridView1.DataSource = query.ToList();

        }

        private void button2_Click(object sender, EventArgs e)
        {
          dataGridView1.ExportToCSV(@"C:\cars-griddump.csv"); 
         //Added Class Max showed me.  This works, I have only tested it on a small
         // XML file so far but it seems to work exactly as I wanted.
        }
    }
}

这将元素直接放在car元素下面。当它到达feature元素时,应用程序崩溃。 (null ref等。)

因此,在完成这个小项目之前,最后一部分是找出XML汇总。当代码读取汽车元素时,它会获得直接在汽车下的所有子元素。当它到达具有附加子元素的元素并且不将它们添加到datagridview时失败。

//已修复Rollup问题。我花了一段时间! //感谢您的帮助!

3 个答案:

答案 0 :(得分:0)

一种方法是将XML加载到数据集中,然后将数据集保存为CSV。这是最简单的一个。但这对XML树的结构有一定的依赖性。

更新以显示将DataTable保存到csv的示例:

我们可以为DataSet中的每个DataTable调用此方法

void SaveDTtoCSV(DataTable dt)
{
    // Save data to CSV file 
    StreamWriter writer = new StreamWriter(@"c:/dsoutput.csv");
    // First we will write the headers.
    int iColCount = dt.Columns.Count;
    for(int i = 0; i < iColCount; i++)
    {
        writer.Write(dt.Columns[i]);
        if (i < iColCount - 1)
        {
            writer.Write(",");
        }
    }
    writer.Write(writer.NewLine);
    // Now write all the rows.
    foreach (DataRow dr in dt.Rows)
    {
        for (int i = 0; i < iColCount; i++)
        {
            if (!Convert.IsDBNull(dr[i]))
            {
                writer.Write(dr[i].ToString());
            }
            if ( i < iColCount - 1)
            {
                writer.Write(",");
            }
        }
        writer.Write(writer.NewLine);
    }
    writer.Close();
}

答案 1 :(得分:0)

除非您想使用XSLT并XslCompiledTransform查看LINQ to XML。这是简单而直接的前进。要加载XML文件,您将使用XDocument.Load(path)并提取您将使用Decedents("car")方法的car元素。然后简单地循环遍历输出的元素。

var cars = XDocument.Load(path).Decedents("car");

LINQ to SQL

XSLT和XslCompiledTransform:在MSDN上查找xslcompiledtransform

如果您使用的是VS2008,则可以扩展DataGrid并创建一个帮助程序类来处理所有导出需求。

  1. 将此[DataGridViewExtender]添加到项目中,如下所示

    
    namespace System.Windows.Forms
    {
    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using System.IO;

    static class DataGridViewExtender { public static void ExportToCSV(this DataGridView grid, string path) { ExportToFile(grid, path, ","); }

    public static void ExportToFile(this DataGridView grid, string path, string separator) { if (grid.Columns.Count <= 0) { return; } using (var writer = new StreamWriter(path)) { var values = new List<string>(grid.Columns.Count); foreach (DataGridViewColumn column in grid.Columns) { values.Add(column.Name); } writer.WriteLine(string.Join(separator, values.ToArray())); foreach (DataGridViewRow row in grid.Rows) { values.Clear(); foreach (DataGridViewCell cell in row.Cells) { values.Add(string.Format("{0}", cell.Value)); } writer.WriteLine(string.Join(separator, values.ToArray())); } writer.Close(); } }
    public static void ExportToFile(this DataGridView grid, string path, string separator) { if (grid.Columns.Count <= 0) { return; } using (var writer = new StreamWriter(path)) { var values = new List<string>(grid.Columns.Count); foreach (DataGridViewColumn column in grid.Columns) { values.Add(column.Name); } writer.WriteLine(string.Join(separator, values.ToArray())); foreach (DataGridViewRow row in grid.Rows) { values.Clear(); foreach (DataGridViewCell cell in row.Cells) { values.Add(string.Format("{0}", cell.Value)); } writer.WriteLine(string.Join(separator, values.ToArray())); } writer.Close(); } }

  2. button2_Click中的
  3. 调用此方法 } }

答案 2 :(得分:0)

你的问题没有太多细节,但我能做的最好的就是假设你有一个包含汽车相关信息的XML文件,比如

<cars>
  <car>
    <make>Honda</model>
    <model>Odyssey</model>
    <year>2009</year>
  </car>
  <car>
    <make>Toyota</make>
    <model>Sienna</model>
    <year>2010</year>
  </car>
</cars>

然后你想写一个如下所示的CSV:

make   model   year
Honda  Odyssey 2009
Toyota Sienna  2010

由于您已经标记了linq-to-xml,我假设您要使用LINQ,尽管您可能不知道下一步该做什么。尝试使用XDocument.Load加载XML文件。然后,您将使用Element()和Elements()来获取XML结构中的节点。例如,如果xml = XDocument.Load(filename),那么xml.Element("cars")应该为您提供根节点。有了它,您可以使用xml.Element("cars").Elements()来获取所有元素......依此类推。