scott_liv01
scott_liv01

Reputation: 25

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'

Upvotes: 0

Views: 541

Answers (3)

hub
hub

Reputation: 51

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

Upvotes: 0

hub
hub

Reputation: 51

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

Upvotes: 0

vdL
vdL

Reputation: 277

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.

Upvotes: 2

Related Questions