Reputation: 25
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
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
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
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