"C# для профессионалов. Том II" - читать интересную книгу автора (Робинсон Симон, Корнес Олли, Глинн Джей,...)

XML 3.0 (MSXML3.DLL) в C#

Как быть, если имеется большой объем кода, разработанного с помощью синтаксического анализатора компании Microsoft (в настоящее время XML 3.0)? Придется ли его выбросить и начать все сначала? А что если вам удобно использовать объектную модель XML 3.0 DOM? Нужно ли немедленно переключаться на .NET?

Ответом будет — нет. XML 3.0 может использоваться непосредственно в приложениях. Если добавить ссылку на msxml3.DLL в свое решение, то можно будет начать писать некоторый код.

Следующие несколько примеров будут использовать файл books.xml в качестве источника данных. Его можно загрузить с web-сайта издательства Wrox, он также включен в несколько примеров .NET SDK. Файл books.xml является каталогом книг воображаемого книжного склада. Он содержит такую информацию, как жанр, имя автора, цена и номер ISBN. Все примеры кода в этой главе также доступны на web-сайте издательства Wrox: www.wrox.com. Чтобы выполнить эти примеры, файлы данных XML должны находиться в структуре путей, которая выглядит примерно следующим образом:

/XMLChapter/Sample1

/XMLChapter/Sample2

/XMLChapter/Sample3

и т. д. Файлы XML должны находиться в подкаталоге XMLChapter, а код для примеров должен быть в подкаталогах Sample1, Sample2 и т.д. Можно называть каталоги как угодно, но их относительное положение важно. Можно также изменять примеры, чтобы указать желаемое направление. В коде примеров будут сделаны указания, какие строки изменить.

Файл books.xml выглядит следующим образом:

lt;?xml version='1.0'?gt;

lt;!-- Этот файл представляет фрагмент базы данных учета запасов книжного склада --gt;

lt;bookstoregt;

 lt;book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0"gt;

  lt;titlegt;The Autobiography of Benjamin Franklinlt;/titlegt;

  lt;authorgt;

   lt;first-namegt;Benjaminlt;/first-namegt;

   lt;last-namegt;Franklinlt;/last-namegt;

  lt;/authorgt;

  lt;pricegt;8.99lt;/pricegt;

 lt;/bookgt;

 lt;book genre="novel" publicationdate="1967" ISBN="0-201-63361-2"gt;

  lt;titlegt;The Confidence Manlt;/titlegt;

  lt;authorgt;

   lt;first-namegt;Hermanlt;/first-namegt;

   lt;last-namegt;Melvillelt;/last-namegt;

  lt;/authorgt;

  lt;pricegt;11.99lt;/pricegt;

 lt;/bookgt;

 lt;book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6"gt; 

  lt;titlegt;The Gorgiaslt;/titlegt;

  lt;authorgt;

   lt;namegt;Platolt;/namegt;

  lt;/authorgt;

  lt;pricegt;9.99lt;/pricegt;

 lt;/bookgt;

lt;/bookstoregt;

Рассмотрим пример кода, использующего MSXML 3.0 для загрузки окна списка с номерами ISBN из books.xml. Ниже записан код, который можно найти в папке SampleBase1 архива, загружаемого с web-сайта издательства Wrox. Можно скопировать его в Visual Studio IDE или создать новую форму Windows Form с самого начала. Эта форма содержит элементы управления listbox и button. Оба элемента используют имена по умолчанию listBox1 и button1:

namespace SampleBase {

 using System;

 using System.Drawing;

 using System.Collections;

 using System.ComponentModel;

 using System.Windows.Forms;

 using System.Data;

Затем включается пространство имен для ссылки на msxml3.dll. Помните, что ссылку на эту библиотеку необходимо включать в проект (ее можно найти на вкладке COM диалогового окна Add Reference).

 using MSXML2;


 /// lt;summarygt;

 /// Краткое описание Form1.

 /// lt;/summarygt;


 public class Form1 : System.Windows.Forms.Form {

  private System.Windows.Forms.ListBox listBox1;

  private System.Windows.Forms.Button button1;


  /// lt;summarygt;

  /// Необходимая для Designer переменная.

  /// lt;/summarygt;

  private System.ComponentModel.Container components;

Затем объявляется документ DOM на уровне модуля:

  private DOMDocument30 doc;


  public Form1() {

   //

   // Требуется для поддержки Windows Form Designer

   //

   InitializeComponent();


   //

   // TODO: Добавьте любой код конструктора после вызова

   // InitializeComponent

   //

  }


  /// lt;summarygt;

  /// Очистить все использованные ресурсы.

  /// lt;/summarygt;

  public override void Disposed {

   base.Dispose();

   if (components != null) components.Dispose();

  }


#region Windows Form Designer создает код


  /// lt;summarygt;

  /// Необходимый для поддержки Designer метод — не изменяйте

  /// содержимое этого метода редактором кода.

  /// lt;/summarygt;

  private void InitializeComponent() {

   this.listBox1 = new System.Windows.Forms.ListBox();

   this.button1 = new System.Windows.Forms.Button();

   this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Top |

    System.Windows.Forms.AnchorStyles.Left) |

    System.Windows.Forms.AnchorStyles.Right);

   this.listBox1.Size = new System.Drawing.Size(336, 238);

   this.listBox1.TabIndex = 0;

   this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);

   this.button1.Anchor = System.Windows.Forms.AnchorStyles.Bottom;

   this.button1.Location = new System.Drawing.Point(136, 264);

   this.button1.TabIndex = 1;

   this.button1.Text = "button1";

   this.button1.Click += new System.EventHandler(this.button1_Click);

   this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);

   this.ClientSize = new System.Drawing.Size(339, 320);

   this.Controls.AddRange(new System.Windows.Forms.Control[]{this.button1, this.listBox1});

   this.Text = "Form1";

  }

#endregion


  /// lt;summarygt;

  /// Главная точка входа для приложения.

  /// lt;/summarygt;

  [STAThread]

  static void Main() {

   Application.Run(new Form1());

  }

Мы хотим взять номер ISBN из listbox и, используя простой поиск XPath, найти узел книги, который ему соответствует, и вывести текст узла (заглавие книги и цену) в MessageBox. Язык пути доступа XML (XPath) является нотацией XML, которая может использоваться для запроса и фильтрации текста в документе XML. Рассмотрим XPath в .NET позже в этой главе. Вот код обработчика событий для выбора записи в окне списка:

  protected void listBox1_SelectedIndexChanged (object sender, System.EventArgs e){

   string srch=listBox1.SelectedItem.ToString();

   IXMLDOMNode nd=doc.selectSingleNode("bookstore/book[@ISBN='" + srch + "']");

   MessageBox.Show(nd.text);

  }

Теперь мы имеем обработчик события нажатия кнопки. Сначала мы загружаем файл books.xml — обратите внимание, что если файл выполняется не в папке bin/debug или bin/release, необходимо исправить соответствующим образом путь доступа:

  protected void button1_Click(object sender, System.EventArgs e) {

   doc=new DOMDocument30();

   doc.load("..\\..\\..\\books.xml")

Следующие строки объявляют, что узлы являются nodeList узлов книг. В данном случае имеется три узла:

   IXMLDOMNodeList nodes;

   nodes = doc.selectNodes("bookstore/book");

   IXMLDOMNode node=nodes.nextNode();

Мы просматриваем узлы в цикле и добавляем текстовое значение атрибута ISBN в listBox1:

   while(node!=null) {

    listBox1.Items.Add(node.attributes.getNamedItem("ISBN").text);

    node=nodes.nextNode();

   }

  }

 }

}

Вот как выглядит пример во время выполнения:

Это изображение появляется после того, как была нажата кнопка button1 и загрузился listBox1 с номерами ISBN книг. После выбора номера ISBN будет выведено следующее: