Wie gesagt:
Zitat von Abt |
also Rekursiv, am besten über Stack<T> |
damit löst man das stabiler, weil keine Stackoverflow Exception damit entstehen kann, wenn die Rekursion zu tief wird.
Und ansonsten seh ich den Sinn nicht, wieso Du die Console-Commands mit in die Methode haust. Gib doch die gefundenen Elemente via yield zurück.
Das ist auch vom Code-Aufbau dann super einfach mit dem Stack<T> zusammen.
public static void Main()
{
XDocument doc = XDocument.Load("Message.xml");
IEnumerable<XAttribute> attributes = GetCounterAttributes(doc);
foreach (var foundAttribute in attributes)
{
Console.WriteLine(foundAttribute.Value);
}
}
public static IEnumerable<XAttribute> GetCounterAttributes(XDocument doc)
{
XElement? root = doc.Root;
if (root is not null)
{
Stack<XElement> queue = new Stack<XElement>(root.Elements());
while (queue.TryPop(out XElement element))
{
foreach (var childElement in element.Elements())
{
queue.Push(childElement);
}
XAttribute attr = element.Attribute("counter");
if (attr is not null)
{
yield return attr;
}
}
}
}
Oder Du arbeitest mit
Descendants (ist gleich im ersten XML Beispiel in der Doc), dann brauchst Du gar keine Rekursion, sondern bekommst direkt alle Elemente.
IEnumerable<XElement> allElements = doc.Root.Descendants();
IEnumerable<XAttribute> allAttributes = allElements.SelectMany(el => el.Attributes());
IEnumerable<XAttribute> counterAttributes = allAttributes.Where(at => at.Name == "counter");
foreach (var foundAttribute in counterAttributes)
{
Console.WriteLine(foundAttribute.Value);
}