Ватсон Карли
Шрифт:
Чтение и запись XML
Теперь посмотрим, что позволяет делать платформа .NET. Если раньше вы работали с SAX, то
XmlReader
и XmlWriter
вам будут знакомы. Классы на основе XmlReader
предоставляют быстрый курсор только для чтения вперед, который создает поток данных XML для обработки. Так как это потоковая модель, то требования к памяти не очень большие. Однако в ней отсутствует навигационная гибкость и средства чтения/записи, присущие модели DOM. Классы на основе XmlWriter
будут создавать документ XML, который соответствует рекомендациям по пространствам имен XML 1.0 консорциума W3C. XmlReader
и XmlWriter
являются абстрактными классами. Рисунок ниже показывает, какие классы являются производными от XmlReader
и XmlWriter
: XmlTextReader
и XmlTextWriter
работают либо с объектами на основе потока, либо с объектами на основе TextReader
или TextWriter
. XmlNodeReader
использует XmlNode
вместо потока в качестве своего источника. XmlValidatingReader
добавляет DTD и проверку схем и поэтому предлагает проверку данных. Мы рассмотрим это подробнее позже в этой главе. XmlTextReader
XmlTextReader
похож на SAX. Одно из различий заключается в том, что SAX является моделью типа рассылки (push), т.е. посылает данные приложению и разработчик должен быть готов принять их, a XmlTextReader
применяет модель запроса (pull), где данные посылаются приложению, которое их запрашивает. Это предоставляет более простую и интуитивно понятную модель для программирования. Другое преимущество состоит в том, что модель запроса может быть избирательной в отношении данных, посылаемых приложению. Если нужны не все данные, то их не нужно обрабатывать. В модели рассылки все данные XML должны быть обработаны приложением, нужны они ему или нет. Возьмем простой пример считывания данных XML, и затем более внимательно рассмотрим класс
XmlTextReader
. Код можно найти в папке XmlReaderSample1
. Можно заменить метод button1_Click
в предыдущем примере на следующий код. Эту версию данного кода можно найти в папке SampleBase2
загруженного архива кода. Не забудьте изменить: using MSXML2;
на
using System.Xml;
Мы должны это сделать, поскольку используем теперь не MSXML 3.0, а пространство имен
System.Xml
. Нужно также удалить метод listBox1_SelectedIndexChanged
, так как он включает в себя некоторые неподдерживаемые методы и строку: private DOMDocument30 doc;
protected void button1_Click(object sender, System.EventArgs e) {
// Измените этот путь доступа, чтобы найти books.xml
string fileName = "..\\..\\..\\books.xml";
// Создать новый объект TextReader
XmlTextReader tr = new XmlTextReader(fileName);
// Прочитать узел за раз
while(tr.Read) {
if (tr.NodeType == XmlNodeType.Text) listBox1.Items.Add(tr.Value);
}
}
Это
XmlTextReader
в простейшей форме. Сначала создается строковый объект fileName
с именем файла XML. Затем создается новый объект XmlTextReader
, передавая в качестве параметра строку fileName.XmlTextReader
в настоящее время имеет 13 различных перегружаемых конструкторов, которые получают различные комбинации строк (имен файлов и URL), потоков и таблиц имен. После инициализации объекта XmlTextReader
ни один узел не выбран. Это единственный момент, когда узел не является текущим. Когда мы начинаем цикл tr.Read
, первая операция чтения Read
переместит нас в первый узел документа. Обычно это бывает узел Declaration XML. В этом примере при переходе к каждому узлу tr.NodeType
сравнивается с перечислением XmlNodeType
, и когда встречается текстовый узел, значение текста добавляется в listbox
. Вот экран после того, как было загружено окно списка: Существует несколько способов перемещения по документу. Как мы только что видели,
Read
перемещает нас к следующему узлу. Затем можно проверить, имеет ли узел значение (HasValue
) или, как мы скоро увидим, имеет ли узел атрибуты (HasAttributes
). Существует метод ReadStartElement
, который проверяет, является ли текущий узел начальным элементом, и затем перемешает текущую позицию к следующему узлу. Если текущая позиция не является начальным элементом, то порождается исключение XmlException
. Этот метод совпадает с вызовом метода IsStartElement
, за которым следует метод Read
. Методы
ReadString
и ReadCharts
считывают текстовые данные из элемента. ReadString
возвращает строковый объект, содержащий данные, в то время как ReadCharts
считывает данные в заданный массив символов. Метод
ReadElementString
аналогичен методу ReadString
, за исключением того, что при желании можно передать в него имена элемента. Если следующий узел содержимого не является начальным тегом или, если параметр Name
не совпадает с именем (Name
) текущего узла, то порождается исключение. Вот пример того, как это может использоваться (код можно найти в папке XmlReaderSample2
):