Einlesen von “delimited with” Daten – Leicht gemacht mit Hilfe von Custom Attribut

So lange es EDV gibt und wohl auch, so lange es EDV geben wird ist der Austausch von Daten immer wieder ein Thema.

Um Daten zwischen Verschiedenen Systemen auszutauschen sind die Möglichkeiten fast unerschöpflich.

Eine der Möglichkeiten besteht darin Daten in eine Zeichenkennte zu schreiben und die Daten mit einem sogenannten Trennzeichen (Delimiter) zwischen den einzelnen Feldinformationen zu trennen (Auch noch im Zeitalter von Serialisierung und anderen tollen Dingen).

Die meisten Programme können Daten in diesem Format exportieren.

Viel interessanter wird es, wenn man diese Daten in seine eigenen Programmen verarbeiten möchte.

Ich möchte hier eine einfache Möglichkeit zeigen, wie man sich mit ein paar Zeilen Code eine schicke kleine Funktion und ein Custom Attribut schreiben kann die einem dabei behilflich sind, solche Daten einzulesen und diese Daten in Eigenschaften seiner eigenen Klasse zu schreiben.

Hier zuerst das Custom Attribute.  Das bietet schon ein wenig mehr Möglichkeiten als es hier in diesem Beispiel zum Einsatz kommt, aber der Beitrag soll auch nicht eine fertige Lösung darstellen, sondern nur behilflich sein, einen Weg zu zeigen:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class ImportFieldAttribute : Attribute
{
	/// <summary>
	/// Feldtype der zu importierenden Daten
	/// </summary>
	private readonly ImportFieldType fieldType;

	/// <summary>
	/// Position im Segment
	/// </summary>
	private readonly int position;

	/// <summary>
	/// Initializes a new instance of the <see cref="ImportFieldAttribute"/> class.
	/// Für Import von Sätzen mit Trennzeichen
	/// </summary>
	/// <param name="fieldType">Type of the field.</param>
	/// <param name="position">The position.</param>
	/// <param name="length">The length.</param>
	public ImportFieldAttribute(ImportFieldType fieldType, int position)
	{
		this.fieldType = fieldType;
		this.position = position;
	}

	/// <summary>
	/// Feldtype der zu importierenden Daten
	/// </summary>
	public ImportFieldType FieldType
	{
		get
		{
			return this.fieldType;
		}
	}

	/// <summary>
	/// Position im Segment
	/// </summary>
	public int Position
	{
		get
		{
			return this.position;
		}
	}
}

Schauen wir uns nun den Code an der sich mit Hilfe des Custom Attribute an die Daten ran macht.

public static void ImportClassFieldsFrom(object target, string buf, char delimiter)
{
	var fields = buf.Split(delimiter);

	const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public;
	var targetProperties = target.GetType().GetProperties(Flags);
	try
	{
		foreach (PropertyInfo propertyInfo in targetProperties)
		{
			var attribs =
				(ImportFieldAttribute[])propertyInfo.GetCustomAttributes(typeof(ImportFieldAttribute), true);

			if (attribs.Length > 0)
			{
				ImportFieldAttribute attrib = attribs[0];
				if (attrib.Position <= fields.Length)
				{
					var temp = fields[attrib.Position];
					propertyInfo.SetValue(target, temp.TrimEnd(), null);
				}
			}
		}
	}
	catch (Exception ex)
	{
		Exceptions.Log.LogError(buf, ex);
	}

}

Und so verwendet man diese Methode und das Custom Attribute:

Bei der Definition der Klasse, welche die Informationen aus dem “Delimited width” Zeichenkette aufnehmen soll, wende ich nun das Custom Attribute wie folgt an:

public class Palettes
{
	/// <summary>
	/// Gets or sets GrossWeight.
	/// </summary>
	[ImportField(ImportFieldType.Char, 1)]
	public string GrossWeight { get; set; }

	/// <summary>
	/// Gets or sets Height.
	/// </summary>
	[ImportField(ImportFieldType.Char, 2)]
	public string Height { get; set; }

	/// <summary>
	/// Gets or sets Lenght.
	/// </summary>
	[ImportField(ImportFieldType.Char, 3)]
	public string Lenght { get; set; }
}

Um die Klasseneigenschaften meiner Klasse mit den Werten aus der “Delimited width” Zeichenkette zu bekommen wird folgender Methodenaufruf durchgeführt:

var palette = new Palettes());
AttributHelper.ImportClassFieldsFrom(palette, "12,00~15,01~23,00", '~');

Fragen, Anregungen und Kritik wie immer, einfach als Kommentar