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

发布于 2024-08-31 00:55:35 字数 3322 浏览 3 评论 0原文

更新一下就清楚了。

第一步:我有一个 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 应用程序。 它有两个按钮、一个文本框和一个数据网格视图。 按钮一应将 XML 数据加载到数据网格中。 然后按钮二应将 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.
        }
    }
}

这将获取汽车元素正下方的元素。当到达功能元素时,应用程序崩溃。 (空引用等)

因此,在完成这个小项目之前,最后一部分是弄清楚 XML 汇总。当代码读取 car 元素时,它会获取直接位于 car 下的所有子元素。当它到达具有其他子元素的元素并且未将它们添加到 datagridview 时,它会失败。

//汇总问题已修复。不过我花了一段时间! // 谢谢大家的帮助!

Updated to be clear.

Step One: I have a XML file that I want to load into a DatGridView. (Mostly working thanks to Max, but I still have a problem with the XML rollup)

Step Two: Run some code based on user input -- (not part of this solution)

Step Three: Export the DataGridView into a CSV File. (Solved by Max! Thanks Man That was exactly what I was trying to do on that part.)

Using VS 2008 C#

(Created a new project)

Sample from the XML file 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>

This is a winform application.
It has two button, one textbox, and one datagridview.
button one should load the XML data into the datagrid.
Then button two should save the data in the datagridview to a CSV file.

Here is the code I have so far to open and load the xml into the 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.
        }
    }
}

This gets the elements directly below the car element. When it gets to the feature element the application crashes. (null ref etc.)

So the last part of this before I am done with this little project is to figure out the XML rollup. When the code reads the car elements it gets all of the sub elements that are directly under car. It fails when it gets to the element that has additional sub elements and does not add them to the datagridview.

//Rollup problem fixed. It took me a while though!
// Thank you for all of the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

缱倦旧时光 2024-09-07 00:55:35

除非您想使用 XSLT 和 XslCompiledTransform,否则请查看 LINQ to XML。它简单而直接。要加载 XML 文件,您将使用 XDocument.Load(path) 并提取汽车元素,您将使用 Decedents("car") 方法。然后简单地循环将它们写入输出的元素。

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

LINQ to SQL

XSLT 和 XslCompiledTransform:在 MSDN 上查找 xslcompiledtransform

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

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

    <前><代码>
    命名空间 System.Windows.Forms
    {
    使用系统;
    使用 System.Collections.Generic;
    使用 System.Windows.Forms;
    使用 System.IO;

    静态类DataGridViewExtender
    {
    public static void ExportToCSV(此DataGridView网格,字符串路径)
    {
    ExportToFile(网格, 路径, ",");
    }

    public static void ExportToFile(此 DataGridView 网格、字符串路径、字符串分隔符)
    {
    if (grid.Columns.Count <= 0)
    { 返回; }

    使用 (var writer = new StreamWriter(path))
    {
    var value = new List(grid.Columns.Count);

    foreach(grid.Columns 中的 DataGridViewColumn 列)
    {
    值.Add(列.名称);
    }
    writer.WriteLine(string.Join(separator, value.ToArray()));
    foreach(grid.Rows 中的 DataGridViewRow 行)
    {
    值.Clear();
    foreach(row.Cells 中的 DataGridViewCell 单元格)
    {
    value.Add(string.Format("{0}", cell.Value));
    }
    writer.WriteLine(string.Join(separator, value.ToArray()));
    }
    作者.关闭();
    }
    }

    <代码>}
    }

  2. 在button2_Click中调用该方法

    <代码>
    私人无效button2_Click(对象发送者,EventArgs e)
    {
    dataGridView1.ExportToCSV(@"C:\griddump.csv");
    }

Unless you want to use XSLT and XslCompiledTransform look at LINQ to XML. It is simple and strait forward. To load XML file you would use XDocument.Load(path) and to extract car element(s) you would use Decedents("car") method. And then simply loop over elements writing them to output.

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

LINQ to SQL

XSLT and XslCompiledTransform: look for xslcompiledtransform on MSDN

If you are using VS2008 you can extend DataGrid and create a helper class to handle all of your exporting needs.

  1. Add this [DataGridViewExtender] to your project as seen below

    
    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(); } }

    }
    }

  2. in button2_Click call this method


    private void button2_Click(object sender, EventArgs e)
    {
    dataGridView1.ExportToCSV(@"C:\griddump.csv");
    }

合久必婚 2024-09-07 00:55:35

你的问题没有太多细节,但我能做的最好的事情就是假设你有一个包含与汽车相关的信息的 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() 来获取所有元素...等等。

There's not much detail in your question, but the best I can do is assume that you've got an XML file that contains information related to cars, like

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

And then you want to write a CSV that looks like this:

make   model   year
Honda  Odyssey 2009
Toyota Sienna  2010

Since you have tagged linq-to-xml, I assume you want to use LINQ, though you might not know what to do next. Try using XDocument.Load to load your XML file. You'll then use Element() and Elements() to get at the nodes in the XML structure. For example, if xml = XDocument.Load(filename), then xml.Element("cars") should give you the root node. With that, you can use xml.Element("cars").Elements() to get all of the elements... and so on and so forth.

孤檠 2024-09-07 00:55:35

一种方法是将 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();
}

One way is to load the XML in to a dataset and then save the dataset to a CSV. This is the easiest one. But this has some dependency the structure of the XML tree.

Update to show a sample to save DataTable to csv:

We can call this method for each DataTable in the DataSet

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文