2006/11/21

XML in .NET 2.0

Heute mal wieder ein fachlicher Post ...
Eine Aufgabe für die Uni erforderte das Bearbeiten einer XML-Datei. Dabei geht es um das Zählen der Elemente mit einem bestimmten Namen.

Dabei ist die XML-Datei wie folgt aufgebaut:
//... XML-Markup
//<typecollection>
// <types library="ABC">
// <type name="nameABC1">
// <members>
// <membertype>Constructor</membertype>
// </members>
// <members>
// <membertype>Method</membertype>
// </members>
// </type>
// </types>
// <types library="CDE">
// <type name="nameCDE1">
// <members>
// <membertype>Constructor</membertype>
// </members>
// </type>
// </types>
//</typecollection>


So weit so gut.
Was soll damit nun gemacht werden?
1.) Zähle die Menge der Elemente "Type"
2.) Benenne das Elemente vom Type "Type" welches die meisten Kindelemente vom Type "MemberType" mit dem Wert "Method" hat.

Lösung:
Ich verwende dazu den im .NET 2.0 Framework beliebten XMLTextReader, der sequentiell ein XML-Dokument durchläuft und bei jedem Element stehenbleibt und somit eine Aktion ermöglicht.
Folgende Lösung zu 1.):
// Create XMLTextReader with xml file
XmlReader reader = new XmlTextReader("myXmlFile.xml");
//Moves the reader to the root element
reader.MoveToContent();


int currentCounter = 0;
while (reader.Read())
{
// If the element is "Type" and a start-element (without closing-tags would be counted too)
if (reader.Name.Equals(elementName) && reader.IsStartElement())
{
currentCounter++;
}
}


Kurzum:

  1. Erstelle einen XmlReader mit dem dazu zu bearbeitenden Dokument
  2. Setze den Reader auf den Beginn des Inhalts der XML-Datei
  3. Lese die komplette Datei über eine while-Schleife
  4. Wenn das jeweilige Element ein Starttag für das Element "Type" ist, zähle den Counter hoch
Ganz einfach also. Demnächst folgt noch eine alternative Lösung mittels XML-DOM (Document Object Model) ...

Folgende Lösung zu 2.):
// Create XMLTextReader with xml file
XmlReader reader = new XmlTextReader("myXmlFile.xml");
//Moves the reader to the root element
reader.MoveToContent();

int currentCounter = 0;
string currentClassName = "";
int highestCounter = 0;
string highestClassName = "";
while (reader.Read())
{
// If element = className and node is startelement
if (reader.Name.Equals(className) && reader.NodeType == XmlNodeType.Element)
{
// Read value of attribute 'Name' and set currentCounter = 0
currentClassName = reader.GetAttribute("Name");
currentCounter = 0;
}
// If element = memberType and element is startelement
if (reader.Name.Equals(memberTypeName) && reader.NodeType == XmlNodeType.Element)
{
// If element = memberTypeMethodType
if (reader.ReadElementString(memberTypeName).Equals(memberTypeMethodType))
{
// Increment currentCounter
currentCounter++;
}
}
// If element = className and node is endelement
if (reader.Name.Equals(className) && reader.NodeType == XmlNodeType.EndElement)
{
// Write output to console
Console.WriteLine("Die Klasse '{0}' hat {1} Methoden.", currentClassName, currentCounter.ToString());
// If currentCounter greater than highestCounter ...
if (currentCounter > highestCounter)
{
// ... set variables to save the classname and counter
highestCounter = currentCounter;
highestClassName = currentClassName;
}
}
}

Kurzum:

  1. Erstelle einen XmlReader mit dem dazu zu bearbeitenden Dokument
  2. Setze den Reader auf den Beginn des Inhalts der XML-Datei
  3. Lese die komplette Datei über eine while-Schleife
  4. Wenn das jeweilige Element ein Starttag für das Element "Type" ist, lies das Attribut Name um zu wissen bei welchem 'Type' man ist
  5. Wenn das aktuelle Element 'MemberType' und der Wert 'Method' ist (ausgelesen durch
    ReadElementString()), zähle den Counter um eins hoch
  6. Wenn das Element 'Type' als schließendes Element auftaucht, überprüfe ob der aktuelle Wert höher als der letzte höchste Wert war und merke ihn Dir ggf. als neuen höchsten Wert

Das war's. Die Schritte 4-6 kann man vielleicht auch eleganter über ein switch-Statement machen, aber der Einfachheit halber habe ich mich dafür entschieden :-)

P.S.: Sorry für die unvorteilhafte Einrückung des Quelltextes, aber ich denke es geht gerade noch so. Falls jemand Probleme dabei hat, einfach Kommentar posten ...

Keine Kommentare: