Suche: AM

XML-Dokument mit LINQ to XML verarbeiten 👍 👎

Obwohl andere Formate wie beispielsweise JSON immer mehr Verbreitung gewinnen, bleibt es natürlich nötig, XML verarbeiten zu können – mit diesem Beitrag möchte ich zeigen, wie XML-Dokumente mit LINQ to XML besonders einfach verarbeitet werden können. LINQ selbst werde ich separat noch ausführlich behandeln.

Als Ausgangslage für unser Beispiel soll folgendes XML-Dokument dienen:
Persons.xml
010203040506070809101112131415161718
<personList>    <person id="1">        <firstName>Anders</firstName>        <lastName>Hejlsberg</lastName>    </person>    <person id="2">        <firstName>Bjarne</firstName>        <lastName>Stroustrup</lastName>    </person>    <person id="3">        <firstName>James</firstName>        <lastName>Gosling</lastName>    </person>    <person id="4">        <firstName>Rasmus</firstName>        <lastName>Lerdorf</lastName>    </person></personList>
Wir möchten daraus eine (generische) Liste von Person-Objekten erzeugen. Die Klasse soll auch gleich die Methode zur XML-Verarbeitung erhalten, welche mit LINQ to XML nun besonders einfach umzusetzen ist:
Person.cs
010203040506070809101112131415161718192021222324252627
public class Person {    public int PersonID {        get;        set;    }
public string FirstName { get; set; }
public string LastName { get; set; }

public static List<Person> ParseXML(string xml) { return XElement.Parse(xml) .Descendants("person") .Select(p => new Person() { PersonID = Int32.Parse(p.Attribute("id").Value), FirstName = p.Element("firstName").Value, LastName = p.Element("lastName").Value }).ToList(); }}
Das Vorgehen dürfte eigentlich weitestgehend selbsterklärend sein. Obwohl selbstverständlich mehr Funktionalität zur Verfügung steht, dürften mit diesem kleinen Beispiel bereits die wichtigsten Fälle abgedeckt sein. Weitere Informationen finden sich ausgehend von XDocument im MSDN.

Papierkorb mit C# leeren 👍 👎

Passend zum letzten Beitrag (Datei mit C# in Papierkorb verschieben) soll es noch einmal um den Papierkorb gehen. Um den Papierkorb zu leeren gibt es leider ebenfalls keine in verwaltetem Code zur Verfügung stehende Funktionalität des .NET-Frameworks für C#. Es ist also – wieder einmal – an der Zeit für DllImport.

Wir werden dazu eine Klasse RecycleBin mit integrierten RecycleFlags erstellen:
RecycleBin.cs
010203040506070809101112131415161718
public static class RecycleBin {    public static void Clear(RecycleFlags recycleFlags = RecycleFlags.None) {        SHEmptyRecycleBin(IntPtr.Zero, null, recycleFlags);    }

[DllImport("shell32")] private static extern uint SHEmptyRecycleBin( IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags );
public enum RecycleFlags : uint { None = 0x0, // Standardverhalten NoConfirmation = 0x1, // keine Rückfrage zur Bestätigung NoProgressUI = 0x2, // keine Fortschrittsanzeige NoSound = 0x4 // kein Abschlussgeräusch }}
Die Verwendung gestaltet sich nun wieder gewohnt einfach:
Papierkorb leeren
0102030405
  // Papierkorb leeren (Standard)RecycleBin.Clear();
// Papierkorb ohne Rückfrage leerenRecycleBin.Clear(RecycleBin.RecycleFlags.NoConfirmation);
Im MSDN gibt es wie üblich weitere Details zu SHEmptyRecycleBin.

Datei mit C# in Papierkorb verschieben 👍 👎

Leider bietet das .NET-Framework mit C# standardmäßig keine in verwaltetem Code implementierte Möglichkeit, Dateien in den Papierkorb zu verschieben statt direkt zu löschen (mit VB.NET interessanterweise jedoch schon).

Es ist möglich, die entsprechende Funktionalität aus VB.NET auch in C# zu verwenden – dazu muss lediglich ein Verweis auf die Assembly Microsoft.VisualBasic ergänzt werden. Anschließend funktioniert folgender Aufruf:
VB.NET-Funktionalität verwenden
01
FileSystem.DeleteFile("Datei.ext", UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
Alternativ lässt sich eine Erweiterungsmethode für FileInfo schreiben, welche mittels DllImport direkt auf die entsprechende Funktionalität der Windows-API zurückgreift. Dazu implementieren wir folgende Klasse:
Erweiterungsmethode für C# per Interop
010203040506070809101112131415161718192021222324252627
public static class RecycleBinExtension {    public static void SendToRecycleBin(this FileInfo fileInfo) {        SHFILEOPSTRUCT lpFileOp = new SHFILEOPSTRUCT {            wFunc  = 0x03,  // FO_DELETE            pFrom  = fileInfo.FullName + "\0\0",            fFlags = 0x40   // FOF_ALLOWUNDO        };
SHFileOperation(ref lpFileOp); }

[DllImport("shell32")] private static extern int SHFileOperation(ref SHFILEOPSTRUCT lpFileOp);
[StructLayout(LayoutKind.Sequential)] private struct SHFILEOPSTRUCT { public IntPtr hwnd; public uint wFunc; public string pFrom; public string pTo; public ushort fFlags; public bool fAnyOperationsAborted; public IntPtr hNameMappings; public string lpszProgressTitle; }}
Zusätzliche Funktionalität habe ich absichtlich außer Acht gelassen. Die Verwendung gestaltet sich nun sehr intuitiv:
Erweiterungsmethode verwenden
0102
FileInfo fileInfo = new FileInfo("Datei.ext");fileInfo.SendToRecycleBin();
Im MSDN finden sich weiterführende Informationen zu SHFileOperation und SHFILEOPSTRUCT.

Ping per C# 👍 👎

Zwar könnte man hier ähnlich wie im Artikel Konsolenausgabe in C# verwenden für traceroute beschrieben vorgehen, jedoch bietet es sich an, die Ping-Klasse des .NET-Frameworks zu verwenden. Diese möchte ich mit diesem Beitrag kurz vorstellen, da sie interessanterweise zu den doch eher unbekannteren Funktionalitäten gehört.
Ping-Klasse verwenden
010203040506
using(Ping ping = new Ping()) {    PingReply reply = ping.Send("coders-online.net");
long time = reply.RoundtripTime; // 19 IPStatus status = reply.Status; // Success}
Es können durch entsprechende Überladungen weiterführende Optionen wie die zu übertragenden Daten festgelegt werden. Durch die seit .NET 4.5 verfügbare Methode SendPingAsync besteht außerdem auch die Möglichkeit, nach dem komfortablen und nicht-blockierenden async/await-Muster vorzugehen.

Grad-Angaben für trigonometrische Funktionen in C# 👍 👎

In einem Gespräch wurde mir kürzlich vom "seltsamen" Verhalten trigonometrischer Methoden wie Math.Sin oder Math.Cos berichtet. Nun lag das Problem jedoch weniger an C# (ohnehin kaum vorstellbar Smiley: winking), sondern vielmehr an den übergebenen Werten – diese lagen nämlich in Grad vor, wobei C# das Bogenmaß erwartet.

Glücklicherweise lassen sich die Werte jedoch schnell und problemlos jeweils zueinander umrechnen:
Umrechung von Grad <-> Bogenmaß
010203040506070809
  // Grad zu Bogenmaß umrechnenpublic static double DegToRad(double degrees) {    return (degrees * (Math.PI / 180));}
// Bogenmaß zu Grad umrechnenpublic static double RadToDeg(double radians) { return (radians * (180 / Math.PI));}
Entsprechende Funktionen habe ich im Rahmen von "PHP-Funktionen in C#" schon einmal zur Verfügung gestellt:

Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche