简体   繁体   中英

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

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'

You should add the namespace and use it in the Descendants invocation:

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

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.

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