ADO.NET. Управление базами данных. Связь по схеме OLE DB провайдера. Коррекция стилей DataGridView, страница 27

        WriteAttribute(a);

      if (node.ChildNodes.Count == 0)

      {

        SelectionColor = Color.Blue;

        SelectedText = " />\n";

      }

      else

      {

        SelectionColor = Color.Blue;

        SelectedText = ">";

        if (node.ChildNodes.Count > 0 && node.FirstChild.NodeType != XmlNodeType.Text)

           SelectedText = "\n";

        foreach (XmlNode n in node.ChildNodes)

           WriteChildren(n);

        EndTag(node);

      }

      tagLevel--;

      break;

    case XmlNodeType.Text:

      SelectionColor = Color.Black;

      SelectedText = node.Value;

      break;

    case XmlNodeType.Comment:

      SelectionColor = Color.Green;

      SelectedText = "<!-- " + node.Value + "-->\n";

      break;

   }

  }

  void StartTag(XmlNode node)

  {

   SelectionColor = Color.Blue;

   SelectionIndent = indentLen * tagLevel;

   SelectedText = "<";

   SelectionColor = Color.Brown;

   SelectedText = node.Name;

  }

  void EndTag(XmlNode node)

  {

   SelectionColor = Color.Blue;

   SelectionIndent = indentLen * tagLevel;

   SelectedText = "</";

   SelectionColor = Color.Brown;

   SelectedText = node.Name;

   SelectionColor = Color.Blue;

   SelectedText = ">\n";

  }

  void WriteAttribute(XmlAttribute a)

  {

   SelectionColor = Color.Red;

   SelectedText = " " + a.Name;

   SelectionColor = Color.Blue;

   SelectedText = "=\"" + a.Value + "\"";

  }

}

Алгоритм метода WriteChildren напоминает тот, что был использован в методе ParseXml. В обоих случаях мы анализируем тип узла и разветвляем алгоритм в зависимости от его значения (перечисления XmlNodeType). Отличие состоит в том, что WriteChildren использует рекурсию для отображения узлов, вложенных в поддерево XML-документа.

Вывод и форматирование текста производится с помщью свойств класса RichTextBox, главным из которых следует считать свойство SelectedText. Переменная tagLevel помогает отслеживать отступы текста при выводе тегов XML-документа в окно RichTextBox. На рис.?  показано окно компонента XmlRichTextBox, внедренного в правую панель компонента SplitContainer.

Разместить компонент на форме можно как в режиме дизайна, так и с помощью кода. Второй способ немного сложнее, поэтому выберем его. Добавьте в класс формы главного окна приложения новый метод ShowXml, в котором мы программным способом создадим два элемента формы и вставим их в коллекцию дочерних элементов splitMain.Panel2 (splitMain — это контейнер типа SplitContainer, а Panel2 — это его правая панель). Доступ к коллекции типа ControlCollection, как обычно, дает свойство Controls.

  void ShowXml(string fileName)

  {

   Label title = new Label();

   splitMain.Panel2.Controls.Add(title);

   title.Font = new Font("Comic Sans MS", 10, FontStyle.Bold);

   title.ForeColor = Color.DarkGreen;

   title.Text = "Parsing XML-document (Students.xml)";

   title.AutoSize = true;

   XmlRichTextBox box = new XmlRichTextBox();

   splitMain.Panel2.Controls.Add(box);

   box.Location = new Point(5, 25);

   box.Size = new Size(260, 250);

   box.ShowXml(FindAFile(fileName), "/StudentsList");

  }

Самым интересным для вас должен быть способ заполнения списка узлов (XmlNodeList), который производится с помощью строки "/StudentsList". На самом деле эта строка представляет собой выражение языка XPath — отдаленного аналога языка запросов SQL. Язык запросов SQL позволяет отбирать строки таблиц из базы данных, а язык XQuery позволяет выбирать поддерево из дерева XML-документа. Заметим, что язык XPath является первым приближением к стандарту XQuery, разработанному международной организацией W3C.

Отбор узлов первого уровня (уровень определен XPath-выражением "/StudentsList") из дерева XML-документа производит метод SelectNodes класса XmlDocument (см. оператор: nodes = doc.SelectNodes(xPath);). Он возвращает узлы дерева в виде списка XmlNodeList. Далее, в цикле прохода по всем узлам списка, мы вызываем рассмотренный выше метод WriteChildren и передаем ему ссылку на текущий узел.