Страницы

Поиск по вопросам

четверг, 30 мая 2019 г.

Как вывести файл Xml деревом в консоль с рекурсией. Вроде все читается, но вот как вывести именно деревом, как и сам файл Xml никак не соображу

вот код
using System.Text; using System.Xml; using System.Xml.Linq; using System.IO;
namespace TestApp_Dipl { class Program { static int iter; static void Main(string[] args) { Program ThisClass = new Program(); Console.WriteLine("Main"); XmlDocument XmlDoc = new XmlDocument(); XmlDoc.Load("File.xml"); XmlNodeList _fnames = XmlDoc.GetElementsByTagName("CD"); Console.WriteLine(_fnames.Count.ToString()); ThisClass.GetNodes(_fnames);

Console.ReadKey(); }
void GetNodes(XmlNodeList NodeListVar) { int i = 1; foreach (XmlNode el in NodeListVar) { if (el.HasChildNodes) { Console.WriteLine(i++ + ". " + el.Name); GetNodes(el.ChildNodes); } else { Console.WriteLine("-> " + el.InnerText); } } }
} }
Xml file.xml
Empire Burlesque Bob Dylan USA Columbia 10.90 1985 Hide your heart Bonnie Tyler UK CBS Records 9.90 1988
Хотелось бы в консоли получить так:
CATALOG 1.CD TITLE Empire Burlesque ARTIST Bob Dylan COUNTRY USA COMPANY Columbia PRICE 10.90 YEAR 1985 2.CD TITLE Hide your heart ARTIST Bonnie Tyler COUNTRY UK COMPANY CBS Records PRICE 9.90 YEAR 1988


Ответ

Если вам не требуется специфический для класса XmlDocument функционал, то проще воспользоваться XDocument из пространства имен System.Xml.Linq. Это позволит получить более компактный код.
Для вывода на консоль в том виде, который вы указали есть три пути.
1. Рекурсивный обход дерева XML
Реализуется довольно просто:
static void Main(string[] args) { XElement doc = XElement.Load(@"H:\test.xml"); PrintElementV1(doc); Console.ReadKey(); }
static void PrintElementV1(XElement elem) { if (elem.Elements().Count() > 0) { Console.WriteLine(elem.Name); foreach (XElement e in elem.Elements()) { PrintElementV1(e); } } else { Console.WriteLine("{0}: {1}", elem.Name, elem.Value); } }
Но вставить в этот вод избирательную нумерацию конкретных элементов без "костылей" не выйдет. "Костыль" для нумерации может выглядеть так:
static void PrintElementV1(XElement elem, int num) { if (elem.Elements().Count() > 0) { Console.WriteLine("{0}. {1}", num, elem.Name); int i = 1; foreach (XElement e in elem.Elements()) { PrintElementV1(e, i++); } } else { Console.WriteLine("{0}: {1}", elem.Name, elem.Value); } }
При этом будут пронумерованы все элементы кроме тех, которые не содержат в себе других элементов.
2. Фиксированный обход дерева XML
С точки зрения дерева, рекурсия сохраняется, такова уж структура дерева, но если эта структура фиксирована и известна, то можно обойтись без рекурсивного вызова методов а использовать цепочку вызовов в цикле. Покажу на примере:
static void Main(string[] args) { XElement doc = XElement.Load(@"H:\test.xml"); Console.WriteLine(doc.Name); PrintCDList(doc); Console.ReadKey(); }
static void PrintCDList(XElement elem) { int i = 1; foreach (XElement e in elem.Elements()) { Console.WriteLine("{0}. {1}", i++, e.Name); PrintContent(e); } }
static void PrintContent(XElement elem) { foreach (XElement e in elem.Elements()) { Console.WriteLine("{0}: {1}", e.Name, e.Value); } }
как видите, рекурсия отсутствует, но если структура XML будет отличаться от заложенной в коде, "все превратится в тыкву" и будет давать неверные результаты.
3. Ручной парсинг
Можно выполнить всю работу руками, получив исходный текст XML в виде текста. Для этого можно воспользоваться любым известным вам способом получения текста из файла.
Далее к строке исходного XML текста применяем всевозможные регулярные выражения или другие известные вам способы преобразования строки до получения строки или массива строк нужного вида и выводим полученное.
Приводить код данного способа не стану, так как вариантов для подобного решения существует масса, а взглядов на то, как это сделать правильно еще больше. К тому же, я сильно сомневаюсь, что подобный вариант будет существенно производительнее чем два предыдущих, скорее наоборот.
Выбирайте какой вариант вам больше подходит =)
PS: Если важно использовать именно XmlDocument, пишите в комментарии, дополню соответствующим примером.

Комментариев нет:

Отправить комментарий