简体   繁体   English

使用linq在C#中将XML解析为CSV

[英]Parsing XML through to CSV in C# using linq

I am trying to parse attributes of an xml file into a csv file, the code checks out and runs with no errors and an output CSV file is generated but contains no data 我正在尝试将xml文件的属性解析为csv文件,代码签出并运行没有错误,并且生成了输出CSV文件,但不包含任何数据

I think the problem may lie within the appending of the elements as when i tried to append another declared string to the string builder, it did not print anything out still. 我认为问题可能在于元素的附加,因为当我尝试将另一个声明的字符串附加到字符串生成器时,它仍然无法打印出任何内容。 I have also tried changing the descendants just in case there was an error here but nothing seemed to work 我还尝试过更改后代,以防万一这里有错误,但似乎无济于事

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


namespace Test
{
    class Program
    {
        public static void Main()
        {
            StringBuilder sb = new StringBuilder();
            string delimiter = ",";
            XDocument.Load(@"C:\Users\livingss\Desktop\XML - CSV\xml\Xml\----------.xml").Descendants("Param").ToList().ForEach(
                element => sb.Append(element.Attribute("Name").Value
                + delimiter
                + element.Attribute("PNum").Value
                + "\r\n"));

            Console.WriteLine(sb);
            StreamWriter sw = new StreamWriter(@"C:\Users\livingss\Desktop\XML - CSV\Result.csv");
            sw.WriteLine(sb.ToString());
            sw.Close();
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<Equipment EType="0000" Name="PlaceHolder" Version="$Revision: 2$" xmlns="urn:equipment-type">
    <EqAttributes />
    <EqVariant />
    <EqModules />
    <EqLogging />
    <EqParameters>
        <Param Name="Not Used" PNum="1">
            <Desc>Spare</Desc>
        </Param>
        <Param Name="Equipment Status" PNum="2" Min="0" Max="8" Un="1">
            <vMap>
                <Opt Name="Stopped">0</Opt>
                <Opt Name="Starting">1</Opt>
                <Opt Name="Running">2</Opt>
                <Opt Name="Stopping">3</Opt>
                <Opt Name="Standby">4</Opt>
                <Opt Name="Idle">5</Opt>
                <Opt Name="Sleep">6</Opt>
                <Opt Name="Hibernate">7</Opt>
                <Opt Name="Faulted">8</Opt>
            </vMap>
        </Param>
        <Param Name="Not Used" PNum="3" Min="0" Max="5" Un="3">
            <Desc>Spare</Desc>
        </Param>
    </EqParameters>
    <EqConfiguration>
    </EqConfiguration>
</Equipment>

The expected output should be the attributes for Param which are 'Name and 'PNum' the output for the first row should be 'Not Used,1' 预期的输出应为Param的属性,即“名称”和“ PNum”,第一行的输出应为“未使用,1”

You should add the namespace and use it in the Descendants invocation: 您应该添加名称空间并在Descendants调用中使用它:

XNamespace urn="urn:equipment-type";     

XDocument.Load(filePath).Descendants(urn + "Param").ToList().ForEach(...

Without the namespace I also don't get any results to enumerate over. 没有命名空间,我也不会得到任何枚举的结果。

For me the problems lies in the way you write the file. 对我来说,问题在于您编写文件的方式。 Try and replace that: 尝试并替换为:

 StreamWriter sw = new StreamWriter(@"C:\Users\livingss\Desktop\XML - CSV\Result.csv");
 sw.WriteLine(sb.ToString());
 sw.Close();

with that: 接着就,随即:

 var path = @"C:\Users\livingss\Desktop\XML - CSV\Result.csv";
 File.WriteAllText(path, sb.ToString());

There you go ! 你去!

StringBuilder sb = new StringBuilder();
string delimiter = ",";

XmlDocument doc = new XmlDocument();
doc.Load(@"file.xml");
var paramElements = doc.GetElementsByTagName("Param");
for (int i = 0; i < paramElements.Count; i++)
{
    var currentElt = paramElements.Item(i);
    sb.Append(currentElt.Attributes.GetNamedItem("Name").Value);
    sb.Append(delimiter);
    sb.Append(currentElt.Attributes.GetNamedItem("PNum").Value);
    sb.AppendLine();
}

var path = @"Result.csv";
File.WriteAllText(path, sb.ToString());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM