This is skipping rows as reader.ReadString()
moves the cursor forward. reader.Value
is empty.
How can I read this XML into List<LogData> logDatas = new List<LogData>();
?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Xml;
using System.IO;
namespace ReadXML
{
class Program
{
private static string XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + Environment.NewLine +
"<log>" + Environment.NewLine +
" <logData id=\"Alpha\">" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>100</index>" + Environment.NewLine +
" <value>150</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>110</index>" + Environment.NewLine +
" <value>750</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>115</index>" + Environment.NewLine +
" <value>150</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>110</index>" + Environment.NewLine +
" <value>750</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>120</index>" + Environment.NewLine +
" <value>750</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>130</index>" + Environment.NewLine +
" <value>150</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" </logData>" + Environment.NewLine +
" <logData id=\"Bravo\">" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>100</index>" + Environment.NewLine +
" <value>25</value></data>" + Environment.NewLine +
" <data>" + Environment.NewLine +
" <index>110</index>" + Environment.NewLine +
" <value>11</value>" + Environment.NewLine +
" </data>" + Environment.NewLine +
" </logData>" + Environment.NewLine +
"</log>";
}
public static List<LogData> GetLogDatas(string xml)
{
List<LogData> logDatas = new List<LogData>();
string wasteFile = "wasteFile.xml";
File.WriteAllText(wasteFile, xml);
using (XmlReader reader = XmlReader.Create(wasteFile))
{
while (reader.Read())
{
if (reader.IsStartElement())
{
Debug.WriteLine($"LocalName {reader.LocalName}");
if (reader.HasAttributes)
Debug.WriteLine($"Attribute: {reader.GetAttribute("id")}");
//Debug.WriteLine($"Value1 {reader.Value}"); //this is empty
Debug.WriteLine($"Value2 {reader.ReadString()}");
}
else
{
//Debug.WriteLine("not IsStartElement");
}
}
}
return logDatas;
}
}
public class LogData
{
public string ID { get; }
public List<LogPoint> LogPoints { get; } = new List<LogPoint>();
public LogData (string id)
{
ID = id;
}
}
public class LogPoint
{
public int Index { get; }
public double Value { get; }
public LogPoint ( int index, double value)
{
Index = index;
Value = value;
}
}
}
Not sure what do you expect your current code to do, but to parse given xml to given data structure, the following seems to be reasonable approach:
public static List<LogData> GetLogDatas(string xml) {
List<LogData> logDatas = new List<LogData>();
// no need for waste file, use StringReader
using (var sreader = new StringReader(xml))
using (XmlReader reader = XmlReader.Create(sreader)) {
LogData currentData = null;
while (reader.Read()) {
if (reader.IsStartElement("logData")) {
// we are positioned on start of logData
if (currentData != null)
logDatas.Add(currentData);
currentData = new LogData(reader.GetAttribute("id"));
}
else if (reader.IsStartElement("data")) {
// we are on start of "data"
// we always have "currentData" at this point
Debug.Assert(currentData != null);
reader.ReadToFollowing("index");
var index = int.Parse(reader.ReadElementContentAsString());
// check if we are not already on "value"
if (!reader.IsStartElement("value"))
reader.ReadToFollowing("value");
var value = double.Parse(reader.ReadElementContentAsString(), CultureInfo.InvariantCulture);
currentData.LogPoints.Add(new LogPoint(index, value));
}
}
if (currentData != null)
logDatas.Add(currentData);
}
return logDatas;
}