// <copyright file="XMLDataFileParser.cs" company="Oleg V. Polikarpotchkin">
// Copyright © 2008-2009 Oleg V. Polikarpotchkin. All Right Reserved
// </copyright>
// <author>Oleg V. Polikarpotchkin</author>
// <email>ov-p@yandex.ru</email>
// <date>2009-03-09</date>
// <summary>OpenWPFChart library. XML Data File Parser.</summary>
// <revision>$Id: XMLDataFileParser.cs 18093 2009-03-16 04:15:06Z unknown $</revision>
using System;
using System.Collections; // For IList
using System.Collections.ObjectModel; // For ObservableCollection
using System.Xml;
using System.Diagnostics;
using OpenWPFChart.Parts;
namespace ColumnChartControlSample
{
/// <summary>
/// XML Data File Parser
/// </summary>
static class XMLDataFileParser
{
/// <summary>
/// Parses the <paramref name="fileName"/> file.
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="xAxisLabel">The x axis label.</param>
/// <returns><see cref="ItemData"/> collection from the <paramref name="fileName"/> file.</returns>
public static ObservableCollection<ItemData> Parse(string fileName, out string xAxisLabel)
{
xAxisLabel = null;
ObservableCollection<ItemData> items = new ObservableCollection<ItemData>();
using (XmlTextReader reader = new XmlTextReader(fileName))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
ItemData item = null;
if (reader.Name == "SampledCurve")
item = ParseSampledCurve(reader, out xAxisLabel);
else if (reader.Name == "ScatteredPoints")
item = ParseScatteredPoints(reader, out xAxisLabel);
if (item != null)
items.Add(item);
}
}
}
return items;
}
/// <summary>
/// Parses the SampledCurve XML element.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="xAxisLabel">The x axis label.</param>
/// <returns></returns>
static ItemData ParseSampledCurve(XmlTextReader reader, out string xAxisLabel)
{
Debug.Assert(reader.NodeType == XmlNodeType.Element, "reader.NodeType == XmlNodeType.Element");
Debug.Assert(reader.Name == "SampledCurve", "reader.Name == \"SampledCurve\"");
// Item name.
string name = reader["Name"];
xAxisLabel = reader["XAxisLabel"];
// Base types.
Type xBaseType = BaseType(reader["XBaseType"]), yBaseType = BaseType(reader["YBaseType"]);
// Point collection.
IList points = TypedPointCollection(xBaseType, yBaseType);
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "Point")
{
string strX = reader["x"];
if (strX == null)
throw new Exception("SampledCurve Point element x attribute missed.");
string strY = reader["y"];
if (strY == null)
throw new Exception("SampledCurve Point element y attribute missed.");
AddTypedPoint(points, strX, strY, xBaseType, yBaseType);
}
else
throw new Exception(string.Format("Invalid SampledCurve element name {0}.", reader.Name));
}
else if (reader.NodeType == XmlNodeType.EndElement)
{
if (reader.Name == "SampledCurve")
break;
}
}
if (points.Count == 0)
return null;
if (xBaseType == typeof(double))
{
if (yBaseType == typeof(double))
{
SampledCurveData<double, double> itemData = new SampledCurveData<double, double>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<double, double>>)points
};
return itemData;
}
else if (yBaseType == typeof(DateTime))
{
SampledCurveData<double, DateTime> itemData = new SampledCurveData<double, DateTime>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<double, DateTime>>)points
};
return itemData;
}
else if (yBaseType == typeof(object))
{
SampledCurveData<double, object> itemData = new SampledCurveData<double, object>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<double, object>>)points
};
return itemData;
}
}
else if (xBaseType == typeof(DateTime))
{
if (yBaseType == typeof(double))
{
SampledCurveData<DateTime, double> itemData = new SampledCurveData<DateTime, double>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<DateTime, double>>)points
};
return itemData;
}
else if (yBaseType == typeof(DateTime))
{
SampledCurveData<DateTime, DateTime> itemData = new SampledCurveData<DateTime, DateTime>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<DateTime, DateTime>>)points
};
return itemData;
}
else if (yBaseType == typeof(object))
{
SampledCurveData<DateTime, object> itemData = new SampledCurveData<DateTime, object>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<DateTime, object>>)points
};
return itemData;
}
}
else if (xBaseType == typeof(object))
{
if (yBaseType == typeof(double))
{
SampledCurveData<object, double> itemData = new SampledCurveData<object, double>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<object, double>>)points
};
return itemData;
}
else if (yBaseType == typeof(DateTime))
{
SampledCurveData<object, DateTime> itemData = new SampledCurveData<object, DateTime>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<object, DateTime>>)points
};
return itemData;
}
else if (yBaseType == typeof(object))
{
SampledCurveData<object, object> itemData = new SampledCurveData<object, object>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<object, object>>)points
};
return itemData;
}
}
return null;
}
/// <summary>
/// Parses the ScatteredPoints XML element.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="xAxisLabel">The x axis label.</param>
/// <returns></returns>
static ItemData ParseScatteredPoints(XmlTextReader reader, out string xAxisLabel)
{
Debug.Assert(reader.NodeType == XmlNodeType.Element, "reader.NodeType == XmlNodeType.Element");
Debug.Assert(reader.Name == "ScatteredPoints", "reader.Name == \"ScatteredPoints\"");
// Item name.
string name = reader["Name"];
xAxisLabel = reader["XAxisLabel"];
// Base types.
Type xBaseType = BaseType(reader["XBaseType"]), yBaseType = BaseType(reader["YBaseType"]);
// Point collection.
IList points = TypedPointCollection(xBaseType, yBaseType);
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "Point")
{
string strX = reader["x"];
if (strX == null)
throw new Exception("ScatteredPoints Point element x attribute missed.");
string strY = reader["y"];
if (strY == null)
throw new Exception("ScatteredPoints Point element y attribute missed.");
AddTypedPoint(points, strX, strY, xBaseType, yBaseType);
}
else
throw new Exception(string.Format("Invalid ScatteredPoints element name {0}.", reader.Name));
}
else if (reader.NodeType == XmlNodeType.EndElement)
{
if (reader.Name == "ScatteredPoints")
break;
}
}
if (points.Count == 0)
return null;
if (xBaseType == typeof(double))
{
if (yBaseType == typeof(double))
{
ScatteredPointsData<double, double> itemData = new ScatteredPointsData<double, double>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<double, double>>)points
};
return itemData;
}
else if (yBaseType == typeof(DateTime))
{
ScatteredPointsData<double, DateTime> itemData = new ScatteredPointsData<double, DateTime>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<double, DateTime>>)points
};
return itemData;
}
else if (yBaseType == typeof(object))
{
ScatteredPointsData<double, object> itemData = new ScatteredPointsData<double, object>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<double, object>>)points
};
return itemData;
}
}
else if (xBaseType == typeof(DateTime))
{
if (yBaseType == typeof(double))
{
ScatteredPointsData<DateTime, double> itemData = new ScatteredPointsData<DateTime, double>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<DateTime, double>>)points
};
return itemData;
}
else if (yBaseType == typeof(DateTime))
{
ScatteredPointsData<DateTime, DateTime> itemData = new ScatteredPointsData<DateTime, DateTime>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<DateTime, DateTime>>)points
};
return itemData;
}
else if (yBaseType == typeof(object))
{
ScatteredPointsData<DateTime, object> itemData = new ScatteredPointsData<DateTime, object>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<DateTime, object>>)points
};
return itemData;
}
}
else if (xBaseType == typeof(object))
{
if (yBaseType == typeof(double))
{
ScatteredPointsData<object, double> itemData = new ScatteredPointsData<object, double>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<object, double>>)points
};
return itemData;
}
else if (yBaseType == typeof(DateTime))
{
ScatteredPointsData<object, DateTime> itemData = new ScatteredPointsData<object, DateTime>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<object, DateTime>>)points
};
return itemData;
}
else if (yBaseType == typeof(object))
{
ScatteredPointsData<object, object> itemData = new ScatteredPointsData<object, object>()
{
ItemName = name,
Points = (ObservableCollection<DataPoint<object, object>>)points
};
return itemData;
}
}
return null;
}
/// <summary>
/// Gets the Base Type from the string.
/// </summary>
/// <param name="strXBaseType">Type name string.</param>
/// <returns></returns>
static Type BaseType(string strBaseType)
{
Type baseType = typeof(double);
switch (strBaseType)
{
case "DateTime":
baseType = typeof(DateTime);
break;
case "String":
baseType = typeof(object);
break;
}
return baseType;
}
/// <summary>
/// Gets the Typed point collection.
/// </summary>
/// <param name="xBaseType">Base x Type.</param>
/// <param name="yBaseType">Base y Type.</param>
/// <returns></returns>
static IList TypedPointCollection(Type xBaseType, Type yBaseType)
{
// Point collection.
IList points = null;
if (xBaseType == typeof(double))
{
if (yBaseType == typeof(double))
points = new ObservableCollection<DataPoint<double, double>>();
else if (yBaseType == typeof(DateTime))
points = new ObservableCollection<DataPoint<double, DateTime>>();
else if (yBaseType == typeof(object))
points = new ObservableCollection<DataPoint<double, object>>();
}
else if (xBaseType == typeof(DateTime))
{
if (yBaseType == typeof(double))
points = new ObservableCollection<DataPoint<DateTime, double>>();
else if (yBaseType == typeof(DateTime))
points = new ObservableCollection<DataPoint<DateTime, DateTime>>();
else if (yBaseType == typeof(object))
points = new ObservableCollection<DataPoint<DateTime, object>>();
}
else if (xBaseType == typeof(object))
{
if (yBaseType == typeof(double))
points = new ObservableCollection<DataPoint<object, double>>();
else if (yBaseType == typeof(DateTime))
points = new ObservableCollection<DataPoint<object, DateTime>>();
else if (yBaseType == typeof(object))
points = new ObservableCollection<DataPoint<object, object>>();
}
return points;
}
/// <summary>
/// Adds the typed point to the typed point collection.
/// </summary>
/// <param name="points">The points.</param>
/// <param name="strX">X string value.</param>
/// <param name="strY">Y string value.</param>
/// <param name="xBaseType">Base x Type.</param>
/// <param name="yBaseType">Base y Type.</param>
static void AddTypedPoint(IList points, string strX, string strY, Type xBaseType, Type yBaseType)
{
if (xBaseType == typeof(double))
{
if (yBaseType == typeof(double))
{
double x = double.Parse(strX);
double y = double.Parse(strY);
points.Add(new DataPoint<double, double>(x, y));
}
else if (yBaseType == typeof(DateTime))
{
double x = double.Parse(strX);
DateTime y = DateTime.Parse(strY);
points.Add(new DataPoint<double, DateTime>(x, y));
}
else if (yBaseType == typeof(object))
{
double x = double.Parse(strX);
points.Add(new DataPoint<double, object>(x, strY));
}
}
else if (xBaseType == typeof(DateTime))
{
if (yBaseType == typeof(double))
{
DateTime x = DateTime.Parse(strX);
double y = double.Parse(strY);
points.Add(new DataPoint<DateTime, double>(x, y));
}
else if (yBaseType == typeof(DateTime))
{
DateTime x = DateTime.Parse(strX);
DateTime y = DateTime.Parse(strY);
points.Add(new DataPoint<DateTime, DateTime>(x, y));
}
else if (yBaseType == typeof(object))
{
DateTime x = DateTime.Parse(strX);
points.Add(new DataPoint<DateTime, object>(x, strY));
}
}
else if (xBaseType == typeof(object))
{
if (yBaseType == typeof(double))
{
double y = double.Parse(strY);
points.Add(new DataPoint<object, double>(strX, y));
}
else if (yBaseType == typeof(DateTime))
{
DateTime y = DateTime.Parse(strY);
points.Add(new DataPoint<object, DateTime>(strX, y));
}
else if (yBaseType == typeof(object))
{
points.Add(new DataPoint<object, object>(strX, strY));
}
}
}
}
}