|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Глава 6 Практическая работа с данными в XML-файлах В главе 3 мы уже кратко описывали основные принципы языка XML, которые необходимы для понимания объектной модели сценариев WS XML. В настоящее время применение XML становится все более широким, поэтому настоящая глава посвящена рассмотрению практических примеров сценариев WSH, которые позволяют анализировать и изменять содержимое файлов в формате XML (естественно, описанные методы анализа и модификации XML-файлов могут применяться и в сценариях, которые встроены в HTML-страницы). Как известно, основной целью разработки XML являлось создание простого текстового формата для хранения и передачи структурированной информации (иерархичность и объектность описываемых данных — ключевые свойства XML). Основные задачи, решаемые при помощи этой технологии в бизнес-приложениях, таковы: ? межплатформенный обмен данными между системами разных разработчиков; ? сбор данных из подразделений организации; ? обмен коммерческими документами между предприятиями; ? сбор отчетности государственными органами. Сейчас библиотеки для работы с XML созданы практически для всех популярных систем разработки приложений и систем управления базами данных. При использовании сценариев WSH также нет необходимости писать собственные программы для разбора XML-формата (такие программы называются парсерами), т.к. встроенный в Windows браузер Internet Explorer версии 4.01 и выше имеет в своем составе в качестве СОМ-объекта парсер MSXML — Microsoft XML library. В настоящей главе для простоты и краткости изложения мы будем пользоваться лишь двумя объектными моделями, которые предоставляет MSXML, не затрагивая рассмотрение таких специфических для XML-файлов понятий, как определения DTD — Documents Type Definitions, используемые для описания и проверки структуры XML-документа, или стилевые таблицы XSL — Extensible Stylesheet Language, предназначенные для формирования на основе данных из XML-источника страницы HTML. Записная книжка в формате XML В предыдущей главе мы рассматривали сценарий для работы с записной книжкой, которая хранится в простом текстовом файле book.txt с разделителями. Каждая строка этого файла содержала одну запись в формате Фамилия|Имя|Телефон|Улица|Дом|Кв.|Примечание: Потапов|Сергей|55-55-55|Моховая|3|10|Без примечаний Попов|Андрей|56-56-56|Ленина|3|5|Без примечаний Иванов|Иван|17-17-17|Садовая|4|6|Очень хороший человек Казаков|Сергей|24-19-68|Полежаева|101|22|Тоже очень хороший человек Для преобразования файла book.txt к формату XML мы введем теги, описанные в табл. 6.1. Таблица 6.1. Описание тегов для записной книжки в XML-формате
Иерархия элементов из таблицы 6.1 показана в листинге 6.1. Листинг 6.1. Иерархия XML-элементов для записной книжки<?xml version="1.0" standalone="yes"?> <PhoneList> <Person> <LastName> Фамилия </LastName> <Name> Имя </Name> <Phone> Телефон </Phone> <Street> Улица </Street> <House> Дом </House> <App> Квартира </App> <Note> Примечание </Note> </Person> Другие записи </PhoneList> Файл book.xml для записной книжки формируется в соответствии с листингом 6.1 (листинг 6.2) Листинг 6.2. Содержимое файла book.xml<?xml version="1.0" encoding="windows-1251"?> <PhoneList> <!-- корневой тэг, список людей --> <Person> <LastName>Потапов</LastName> <Name>Сергей</Name> <Phone>55-55-55</Phone> <Street>Моховая</Street> <House>3</House> <App>10</App> <Note>Без примечаний</Note> </Person> <Person> <LastName>Попов</LastName> <Name>Андрей</Name> <Phone>56-56-56</Phone> <Street>Ленина</Street> <House>3</House> <App>5</App> <Note>Без примечаний</Note> </Person> <Person> <LastName>Иванов</LastName> <Name>Иван</Name> <Phone>17-17-17</Phone> <Street>Садовая</Street> <House>4</House> <App>6</App> <Note>Очень хороший человек</Note> </Person> <Person> <LastName>Казаков</LastName> <Name>Сергей</Name> <Phone>24-19-68</Phone> <Street>Полежаева</Street> <House>101</House> <App>22</App> <Note>Тоже очень хороший человек</Note> </Person> </PhoneList> Просмотр XML-файла с помощью объектной модели Internet Explorer 4.0 Если требуется только просматривать и анализировать XML-файл, не модифицируя его, то проще всего воспользоваться объектной моделью MSXML, реализованной в Internet Explorer 4.01. Замечание Описание объектной модели При рассмотрении объектной модели MSXML данные, которые хранятся в XML-файле, удобно представлять в виде иерархического дерева, имеющего один корневой элемент и множество дочерних элементов различного уровня вложенности. Для анализа содержимого XML-файла используются три объекта: XML Document(объект для работы с XML-документом в целом), XML Element(отвечает за работу с каждым из элементов XML-файла) и Element Collection(коллекция XML-элементов, доступ к которым при помощи метода item()возможен по имени или порядковому номеру). Полный набор свойств и методов этих трех объектов мы рассматривать не будем; в табл. 6.2 и 6.3 приведено описание нескольких основных свойств объектов XML Documentи XML Element, некоторые из них понадобятся нам в дальнейшем при составлении сценария на языке JScript для просмотра записной книжки. Таблица 6.2. Свойства объекта
Таблица 6.3. Свойства объекта
Пример сценария С помощью приведенного ниже сценария SortNameMSXML.js все записи из book.xml сортируются по фамилии и отображаются в Блокноте. Напомним, что аналогичную задачу для текстового файла с разделителями book.txt реализует сценарий SortName.js, приведенный в листинге 5.21. Алгоритм работы сценария SortNameMSXML.js, как и SortName.js, сводится к следующим основным шагам. 1. Информация из файла book.xml считывается в массив PersonArr. Каждый элемент массива является экземпляром объекта Person, в котором хранятся все данные для одного человека. 2. Массив PersonArrсортируется по возрастанию фамилий. 3. Содержимое всех записей из массива PersonArrвыводится в текстовый файл out.txt. 4. Файл out.txt открывается в Блокноте. Таким образом, специфика работы с XML-файлом проявляется лишь при считывании данных из файла book.xml в массив PersonArr. Для этого используется функция FileToArray(). Сначала в этой функции создается пустой массив PersonArrи экземпляр XMLобъекта XML Document: PersonArr=new Array(); XML=WScript.CreateObject("MSXML"); В свойство urlобъекта XMLзаписывается путь к файлу book.xml, который хранится в переменной PathBook: XML.url=PathBook; Далее в функции FileToArrayо определяется количество элементов <Person>, т.е. количество записей в книжке (переменная NomRec): NamRec=XML.root.children.item("Person").length; В цикле forпроисходит перебор всех элементов <Person>, которые являются элементами соответствующей коллекции: //Перебираем коллекцию XML-элементов Person for (i=0; i<NomRec; i++) { //Выделяем в коллекции XML-элементов i-й элемент Person XItem=XML.root.children.item("Person", i); //Добавляем новый элемент, в массив объектов Person PersonToArray(XItem); } Как мы видим, каждый элемент <Person>передается в качестве аргумента в функцию PersonToArray(XItem), в которой создается новый экземпляр PersonRecобъекта Person, заполняются поля этого объекта и происходит добавление PersonRecв массив PersonArr: function PersonToArray(XItem) { //Создаем новый экземпляр PersonRec объекта Person PersonRec=new Person(); //Заполняем поля объекта PersonRec PersonRec.LastName=GetTagVal(XItem,"LastName"); PersonRec.Name=GetTagVal(XItem,"Name"); PersonRec.Phone=GetTagVal(XItem,"Phone"); PersonRec.Street=GetTagVal(XItem,"Street"); PersonRec.House=GetTagVal(XItem,"House"); PersonRec.App=GetTagVal(XItem,"App"); PersonRec.Note=GetTagVal(XItem,"Note"); //Сохраняем объект PersonRec в массиве PersonArr[PersonArr.length]=PersonRec; } Поля объекта PersonRecзаполняются с помощью функции GetTagVal(obj, tgName), которая возвращает значение дочернего для элемента objэлемента с именем tgName: function GetTagVal(obj, tgName) { //Возвращаем значение тега tgName return obj.Children.Item(tgName,0).Text; } В листинге 6.3 приводится полный текст сценария SortNameMSXMLjs. Листинг 6.3. Чтение данных из XML-файла с помощью объектной модели Internet Explorer 4.0/*******************************************************************/ /* Имя: SortNameMSXML.js */ /* Язык: JScript */ /* Описание: Записная книжка (данные в XML-файле book.xml). */ /* Вывод всех записей с сортировкой по фамилии с */ /* помощью объектной модели Internet Explorer 4.0 */ /*******************************************************************/ //Объявляем переменные var WshShell,FSO, BasePath, //Путь к текущему каталогу PathBook, //Путь к файлу с данными PathOut, //Путь к выходному файлу FBook, //Файл с данными FOut, //Выходной файл NomRec=0, //Счетчик количества записей PersonRec, //Объект для хранения данных об одном человеке PersonArr; //Массив для хранения объектов PersonRec ForWriting=2; //Константа для создания выходного файла //Конструктор объекта Person function Person(LastName,Name,Phone,Street,House,App,Note) { this.LastName=LastName; //Фамилия this.Name=Name; //Имя this.Phone=Phone; //Телефон this.Street=Street; //Улица this.House=House; //Дом this.App=App; //Квартира this.Note=Note; //Примечание } //Определение значения тега tgName XML-элемента obj function GetTagVal(obj, tgName) { //Возвращаем значение тега tgName return obj.Children.Item(tgName,0).Text; } //Заполнение нового элемента массива function PersonToArray(XItem) { //Создаем новый экземпляр PersonRec объекта Person PersonRec=new Person(); //Заполняем поля объекта PersonRec PersonRec.LastName=GetTagVal(XItem,"LastName"); PersonRec.Name=GetTagVal(XItem,"Name"); PersonRec.Phone=GetTagVal(XItem,"Phone"); PersonRec.Street=GetTagVal(XItem,"Street"); PersonRec.House=GetTagVal(XItem,"House"); PersonRec.App=GetTagVal(XItem,"App"); PersonRec.Note=GetTagVal(XItem,"Note"); //Сохраняем объект PersonRec в массиве PersonArr[PersonArr.length]=PersonRec; } //Создание массива объектов Person function FileToArray() { var XML,NomRec,XItem,ex; //Создаем массив PersonArr PersonArr=new Array(); //Создаем объект MSXML XML=WScript.CreateObject("MSXML"); //Задаем путь к файлу с данными XML.url=PathBook; //Инициализируем счетчик числа элементов Person //в XML-файле NomRec=0; try { //Определяем число элементов Person в XML-файле NomRec=XML.root.children.item("Person").length; if (typeof(NomRec)=="undefined") NomRec=1; } catch (ex) { NomRec=0; } //Перебираем коллекцию XML-элементов Person for (i=0;i<NomRec;i++) { //Выделяем в коллекции XML-элементов i-й элемент Person XItem=XML.root.children.item("Person",i); //Добавляем новый элемент в массив объектов Person PersonToArray(XItem); } } //Запись в выходной файл заголовка отчета function TopReport(Mess) { FOut.WriteLine(Mess); FOut.WriteLine("--------------------"); FOut.WriteLine(""); } //Запись в выходной файл итоговой информации function BottomReport() { FOut.WriteLine("Всего записей: "+NomRec); } //Запись данных из объекта Person в выходной файл function PrintPerson(PersRec) { FOut.WriteLine("Фамилия: "+PersRec.LastName); FOut.WriteLine("Имя: "+PersRec.Name); FOut.WriteLine("Телефон: "+PersRec.Phone); FOut.WriteLine("Улица: "+PersRec.Street); FOut.WriteLine("Дом: "+PersRec.House); FOut.WriteLine("Кв.: "+PersRec.App); FOut.WriteLine("Заметки: "+PersRec.Note); FOut.WriteLine("*********************************"); NomRec++; } //Сортировка массива и вывод его содержимого в выходной файл function ListPersonArray() { var i,a; //Сортировка массива по фамилии PersonArr.sort(SortLastName); //Цикл по всем элементам массива PersonArr for (i=0;i<=PersonArr.length-1;i++) { //Запись информации в выходной файл PrintPerson(PersonArr[i]); } } //Функция для сортировки массива по фамилии function SortLastName(Pers1,Pers2) { if (Pers1.LastName<Pers2.LastName) return -1; else if (Pers1.LastName==Pers2.LastName) return 0; else return 1; } //Вывод содержимого файла с данными function ListFile() { //Считывание данных из файла в массив FileToArray(); //Запись информации из массива в выходной файл ListPersonArray(); } //Просмотр содержимого выходного файла в Блокноте function MakeOut() { //Закрываем выходной файл FOut.Close(); //Открываем выходной файл в Блокноте WshShell.Run("notepad "+PathOut,1); } //Построение путей к файлам function InitPath() { BasePath=WshShell.CurrentDirectory+"\\"; //Путь к файлу с данными PathBook=BasePath+"book.xml", //Путь к выходному файлу PathOut=BasePath+"out.txt"; } //Основная запускная функция function Main() { //Создаем объект WshShell WshShell = WScript.CreateObject("WScript.Shell"); //Определяем пути к файлам InitPath(); //Создаем объект FileSystemObject FSO=WScript.CreateObject("Scripting.FileSystemObject"); //Открываем выходной файл для записи FOut=FSO.OpenTextFile(PathOut,ForWriting,true); //Печатаем заголовок отчета TopReport("Сортировка по фамилии"); //Выводим содержимого файла с данными ListFile(); //Печатаем итоговую информацию BottomReport("Всего записей: "+PersonArr.length); //Открываем выходной файл в Блокноте MakeOut(); } /******************* Начало **********************************/ Main(); /************* Конец *********************************************/ Использование XML DOM для просмотра и изменения ХМL-файла Объектная модель XML DOM (XML Document Object Model, объектная модель документа XML) является рекомендованным корпорацией W3C стандартом, который определяет интерфейсы, с помощью которых приложения могут загружать XML-файл, просматривать его содержимое, производить поиск, добавление, изменение и удаление данных, сохранять сделанные изменения в файле. Отметим, что в модели XML DOM документ в формате XML рассматривается как иерархическое дерево, которое состоит из элементов, называемых узлами (nodes), и имеет один корневой элемент (узел). Замечание Описание модели XML DOM Парсер MSXML поддерживает много объектов, определяемых в модели XML DOM, с помощью которых можно решать связанные с XML задачи различного уровня сложности. Нам в дальнейшем для написания сценариев, которые осуществляют просмотр записной книжки в XML-формате, а также поиск, добавление и удаление записей из этой книжки, понадобятся только три основных объекта: DOMDocument(представляет XML-документ в целом), XMLDOMNode(представляет одиночный XML-элемент, т. е. один узел в дереве) и XMLDOMNodeList(коллекция элементов, являющихся дочерними по отношению к определенному узлу в дереве, доступ к которым возможен по порядковому номеру при помощи метода item()). В свою очередь, объекты DOMDocumentи XMLDOMNodeимеют множество свойств и методов, некоторые из них (включая все свойства и методы, которые используются при написании сценариев для работы с записной книжкой) описаны в табл. 6.4–6.6. Таблица 6.4. Свойства и методы объекта
Таблица 6.5. Свойства объекта
Таблица 6.6. Методы объекта
Просмотр содержимого записной книжки Для того чтобы использовать схему XML DOM в сценарии SortNameMSXML.js, осуществляющем вывод информации из XML-файла book.xml в Блокнот, нужно внести изменения в три функции: GetTagVal(obj, tgName), PersonToArray(XNode)и FileToArray(). Сценарий, который получится в результате этих изменений, назовем SortNameXMLDOM.js. В функции FileToArray()сначала создается пустой массив PersonArrи экземпляр XMLобъекта DOMDocument: PersonArr=new Array(); XML = WScript.CreateObject("Msxml.DOMDocument"); Для загрузки содержимого файла book.xml (путь к этому файлу хранится в переменной PathBook) в объект xml, используется метод load: XML.load(PathBook); Указатель на корневой элемент записывается в переменную Rootс помощью свойства documentElementобъекта XML: Root=XML.documentElement; После этого нам остается в цикле перебрать все элементы Person(для корневого элемента они являются дочерними элементами первого уровня вложенности) и для каждого из них вызвать функцию PersonToArray(): for (i=1; i<=Root.childNodes.length-1; i++) { //Выделяем в коллекции XML-элементов i-й элемент //первого уровня вложенности CurrNode=Root.childNodes.item(i); //Добавляем новый элемент в массив объектов Person PersonToArray(CurrNode); } Функция PersonToArray(XNode)в SortNameXMLDOM.js имеет тот же вид, что и в сценарии SortNameMSXML.js: function PersonToArray(XNode) { //Создаем новый экземпляр PersonRec объекта Person PersonRec=new Person(); //Заполняем поля объекта PersonRec PersonRec.LastName=GetTagVal(XNode,"LastName"); PersonRec.Name=GetTagVal(XNode,"Name"); PersonRec.Phone=GetTagVal(XNode,"Phone"); PersonRec.Street=GetTagVal(XNode,"Street"); PersonRec.House=GetTagVal(XNode,"House"); PersonRec.App=GetTagVal(XNode,"App"); PersonRec.Note=GetTagVal(XNode,"Note"); //Сохраняем объект PersonRec в массиве PersonArr[PersonArr.length]=PersonRec; } Здесь для построения функции GetTagVal(obj, tgName), которая возвращает значение дочернего для элемента objэлемента с именем tgName, используется метод getElementsByTagName, возвращающий коллекцию дочерних элементов с заданным именем: function GetTagVal(obj, tgName) { var ElemList; //Создаем коллекцию дочерних для obj элементов, которые //задаются тегом tgName ElemList=obj.getElementsByTagName(tgName); //Проверяем, есть ли в коллекции ElemList элементы if (ElemList.length>0) //Возвращаем значение первого встретившегося элемента tgName return ElemList.item(0).text else return ""; } В листинге 6.4 приводится полный текст сценария SortNameXMLDOM.js. Листинг 6.4. Чтение данных из XML-файла с помощью XML DOM/*******************************************************************/ /* Имя: SortNameXMLDOM.js */ /* Язык: JScript */ /* Описание: Записная книжка (данные в XML-файле book.xml). */ /* Вывод всех записей с сортировкой по фамилии с */ /* помощью объектной модели XML DOM */ /*******************************************************************/ //Объявляем переменные var WshShell,FSO, BasePath, //Путь к текущему каталогу PathBook, //Путь к файлу с данными PathOut, //Путь к выходному файлу FBook, //Файл с данными FOut, //Выходной файл NomRec=0, //Счетчик количества записей PersonRec, //Объект для хранения данных об одном человеке PersonArr; //Массив для хранения объектов PersonRec ForWriting=2; //Константа для создания выходного файла //Конструктор объекта Person function Person(LastName,Name,Phone,Street,House,App,Note) { this.LastName=LastName; //Фамилия this.Name=Name; //Имя this.Phone=Phone; //Телефон this.Street=Street; //Улица this.House=House; //Дом this.App=App; //Квартира this.Note=Note; //Примечание } //Определение значения тега tgName XML-элемента obj function GetTagVal(obj, tgName) { var ElemList; //Создаем коллекцию дочерних для obj элементов, которые //задаются тегом tgName ElemList=obj.getElementsByTagName(tgName); //Проверяем, есть ли в коллекции ElemList элементы if (ElemList.length>0) //Возвращаем значение первого встретившегося элемента tgName return ElemList.item(0).text else return ""; } //Заполнение нового элемента массива function PersonToArray(XNode) { //Создаем новый экземпляр PersonRec объекта Person PersonRec=new Person(); //Заполняем поля объекта PersonRec PersonRec.LastName=GetTagVal(XNode,"LastName"); PersonRec.Name=GetTagVal(XNode,"Name"); PersonRec.Phone=GetTagVal(XNode,"Phone"); PersonRec.Street=GetTagVal(XNode,"Street"); PersonRec.House=GetTagVal(XNode,"House"); PersonRec.App=GetTagVal(XNode,"App"); PersonRec.Note=GetTagVal(XNode,"Note"); //Сохраняем объект PersonRec в массиве PersonArr[PersonArr.length]=PersonRec; } //Создание массива объектов Person function FileToArray() { var XML,Root,NomRec,CurrNode,ex,i; //Создаем массив PersonArr PersonArr=new Array(); //Создаем объект XML DOM XML = WScript.CreateObject("Msxml.DOMDocument"); //Загружаем XML-документ из файла XML.load(PathBook); //Сохраняем в переменной Root ссылку на корневой элемент документа Root=XML.documentElement; //Перебираем все дочерние элементы первого уровня вложенности //для корневого элемента for (i=1; i<=Root.childNodes.length-1;i++) { //Выделяем в коллекции XML-элементов i-й элемент CurrNode=Root.childNodes.item(i); //Добавляем новый элемент в массив объектов Person PersonToArray(CurrNode); } } //Запись в выходной файл заголовка отчета function TopReport(Mess) { FOut.WriteLine(Mess); FOut.WriteLine("--------------------"); FOut.WriteLine(""); } //Запись в выходной файл итоговой информации function BottomReport(Mess) { FOut.WriteLine(Mess); } //Запись данных из объекта Person в выходной файл function PrintPerson(PersRec) { FOut.WriteLine("Фамилия: "+PersRec.LastName); FOut.WriteLine("Имя: "+PersRec.Name); FOut.WriteLine("Телефон: "+PersRec.Phone); FOut.WriteLine("Улица: "+PersRec.Street); FOut.WriteLine("Дом: "+PersRec.House); FOut.WriteLine("Кв.: "+PersRec.App); FOut.WriteLine("Заметки: "+PersRec.Note); FOut.WriteLine("*********************************"); NomRec++; } //Сортировка массива и вывод его содержимого в выходной файл function ListPersonArray() { var i; //Сортировка массива по фамилии PersonArr.sort(SortLastName); //Цикл по всем элементам массива PersonArr for (i=0;i<=PersonArr.length-1;i++) { //Запись информации в выходной файл PrintPerson(PersonArr[i]); } } //Функция для сортировки массива по фамилии function SortLastName(Pers1,Pers2) { if (Pers1.LastName<Pers2.LastName) return -1; else if (Pers1.LastName==Pers2.LastName) return 0; else return 1; } //Вывод содержимого файла с данными function ListFile() { //Считывание данных из файла в массив FileToArray(); //Запись информации из массива в выходной файл ListPersonArray(); } //Просмотр содержимого выходного файла в Блокноте function MakeOut() { //Закрываем выходной файл FOut.Close(); //Открываем выходной файл в Блокноте WshShell.Run("notepad "+PathOut,1); } //Построение путей к файлам function InitPath() { BasePath=WshShell.CurrentDirectory+"\\"; //Путь к файлу с данными PathBook=BasePath+"book.xml", //Путь к выходному файлу PathOut=BasePath+"out.txt"; } //Основная запускная функция function Main() { //Создаем объект WshShell WshShell = WScript.CreateObject("WScript.Shell"); //Определяем пути к файлам InitPath(); //Создаем объект FileSystemObject FSO=WScript.CreateObject("Scripting.FileSystemObject"); //Открываем выходной файл для записи FOut=FSO.OpenTextFile(PathOut,ForWriting,true); //Печатаем заголовок отчета TopReport("Сортировка по фамилии"); //Выводим содержимого файла с данными ListFile(); //Печатаем итоговую информацию BottomReport("Всего записей: "+PersonArr.length); //Открываем выходной файл в Блокноте MakeOut(); } /******************* Начало **********************************/ Main(); /************* Конец *********************************************/ Добавление информации в записную книжку В принципе можно добавлять информацию в записную книжку, просто записывая строки с соответствующими тегами в текстовый файл book.xml. Однако лучше для этой цели воспользоваться специальными методами XML DOM (в этом случае не нужно, например, заботиться о закрывающих тегах). Для иллюстрации методов XML DOM, позволяющих записывать данные в XML-файл, рассмотрим сценарий AddRecord.js, в котором производится добавление в book.xml следующей записи: <Person> <LastName>Сидоров</LastName> <Name>Aнтон</Name> <Phone>18-18-18</Phone> <Strееt>Саранская</Street> <House>12</House> <App>4</App> <Note>Запись добавлена из сценария</Note> </Person> Процесс добавления записи в книжку осуществляется в функции AddRecord(). Здесь сначала заполняются нужными значениями поля объекта PersonRec(функция MakePersonRec()), а затем данные из PersonRecдобавляются в файл book.xml (функция RecordToFile(PersonRec)): function AddRecord() { //Заполняем поля объекта PersonRec MakePersonRec(); //Сохраняем данные из объекта PersonRec в XML-файле RecordToFile(PersonRec); } Итак, наиболее важной в сценарии является функция RecordToFile(PersonRec). В этой функции сначала создается экземпляр XMLDocобъекта DOMDocumentи с помощью метода loadзагружается файл book.xml: XMLDoc = WScript.CreateObject("Msxml.DOMDocument"); XMLDoc.load(PathBook); Указатель на корневой элемент сохраняется в переменной Root: Root=XMLDoc.documentElement; После этого с помощью метода createElementсоздается новый элемент Person, который затем добавляется в book.xml (метод appendChild): //Создаем XML-элемент Person NewElem=XMLDoc.createElement("Person"); //Добавляем новый элемент в XML-файл Root.appendChild(NewElem); Другие добавляемые элементы ( LastName, Name, Phone, Street, House, Appи Note) должны быть дочерними относительно элемента Person, поэтому в переменной Rootмы сохраним ссылку на последний добавленный элемент Person: Root=Root.lastChild; Все элементы добавляются с помощью вызовов методов createElementи appendChild, например: //Создаем элемент LastName NewElem=XMLDoc.createElement("LastName"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); Содержимое добавляемых элементов (свойство text) берется из соответствующих полей объекта PersRec, например: //Подставляем в качестве содержимого элемента LastName //значение поля LastName объекта PersRec Root.lastChild.text=PersRec.LastName; После того как все нужные элементы добавлены, измененный файл book.xml с помощью метода save сохраняется на жестком диске: XMLDoc.save(PathBook); Полный текст сценария AddRecord.js приводится в листинге 6.5. Листинг 6.5. Добавление данных в XML-файл с помощью XML DOM/*******************************************************************/ /* Имя: AddRecord.js */ /* Язык: JScript */ /* Описание: Записная книжка (данные в XML-файле book.xml). */ /* Вставка новых элементов в XML-файл */ /*******************************************************************/ //Объявляем переменные var WshShell, BasePath, //Путь к текущему каталогу PathBook, //Путь к файлу с данными XMLDoc, //XML-файл с данными NomRec=0, //Счетчик количества записей PersonRec, //Объект для хранения данных об одном человеке PersonArr; //Массив для хранения объектов PersonRec //Инициализируем константы для диалоговых окон var vbYesNo=4,vbQuestion=32,vbInformation=64,vbYes=6,vbOkOnly=0; //Конструктор объекта Person function Person(LastName,Name,Phone,Street,House,App,Note) { this.LastName=LastName; //Фамилия this.Name=Name; //Имя this.Phone=Phone; //Телефон this.Street=Street; //Улица this.House=House; //Дом this.App=App; //Квартира this.Note=Note; //Примечание } //Заполнение полей объекта PersonRec function MakePersonRec() { //Создаем экземпляр PersonRec объекта Person PersonRec=new Person(); //Заполняем поля объекта PersonRec PersonRec.LastName="Сидоров"; PersonRec.Name="Антон"; PersonRec.Phone="18-18-18"; PersonRec.Street="Саранская"; PersonRec.House="12"; PersonRec.App="4"; PersonRec.Note="Запись добавлена из сценария"; } //Сохранение данных из объекта PersonRec в XML-файле function RecordToFile(PersRec) { //Объявляем переменные var Root,NewElem,s; //Создаем объект DOMDocument XMLDoc = WScript.CreateObject("Msxml.DOMDocument"); //Загружаем XML-файл XMLDoc.load(PathBook); //Сохраняем в переменной Root ссылку на корневой элемент //документа Root=XMLDoc.documentElement; //Создаем XML-элемент Person NewElem=XMLDoc.createElement("Person"); //Добавляем новый элемент в XML-файл Root.appendChild(NewElem); //Сохраняем в переменной Root ссылку на последний добавленный //элемент Person Root=Root.lastChild; //Создаем элемент LastName NewElem=XMLDoc.createElement("LastName"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента LastName //значение поля LastName объекта PersRec Root.lastChild.text=PersRec.LastName; //Создаем элемент Name NewElem=XMLDoc.createElement("Name"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента Name //значение поля Name объекта PersRec Root.lastChild.text=PersRec.Name; //Создаем элемент Phone NewElem=XMLDoc.createElement("Phone"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента Phone //значение поля Phone объекта PersRec Root.lastChild.text=PersRec.Phone; //Создаем элемент Street NewElem=XMLDoc.createElement("Street"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента Street //значение поля Street объекта PersRec Root.lastChild.text=PersRec.Street; //Создаем элемент House NewElem=XMLDoc.createElement("House"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента House //значение поля House объекта PersRec Root.lastChild.text=PersRec.House; //Создаем элемент App NewElem=XMLDoc.createElement("App"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента App //значение поля House объекта PersRec Root.lastChild.text=PersRec.App; //Создаем элемент Note NewElem=XMLDoc.createElement("Note"); //Добавляем новый элемент в XML-файл (внутри элемента Person) Root.appendChild(NewElem); //Подставляем в качестве содержимого элемента App //значение поля House объекта PersRec Root.lastChild.text=PersRec.Note; //Сохраняем содержимое XML-файла на диске XMLDoc.save(PathBook); } //Добавление новой записи в книжку function AddRecord() { //Заполняем поля объекта PersonRec MakePersonRec(); //Сохраняем данные из объекта PersonRec в XML-файл RecordToFile(PersonRec); } //Построение путей к файлам function InitPath() { BasePath=WshShell.CurrentDirectory+"\\"; //Путь к файлу с данными PathBook=BasePath+"book.xml"; } //Основная запускная функция function Main() { var Res; //Создаем объект WshShell WshShell = WScript.CreateObject("WScript.Shell"); //Определяем пути к файлам InitPath(); //Запрос на создание нового ключа Res=WshShell.Popup("Добавить запись в \n"+PathBook+"?", 0, "Работа с XML-файлом", vbQuestion+vbYesNo); if (Res==vbYes) { //Нажата кнопка Да //Добавляем новую запись в книжку AddRecord(); //Выводим информацию на экран WshShell.Popup("Новая запись\n\n"+PersonRec.LastName+" "+ PersonRec.Name+"\n"+PersonRec.Phone+"\n"+ PersonRec.Street+", "+PersonRec.House+"-"+PersonRec.App+"\n\n"+ "добавлена в файл "+PathBook, 0, "Работа с XML-файлом", vbInformation+vbOkOnly); } } /******************* Начало **********************************/ Main(); /************* Конец *********************************************/ Поиск и удаление записи из книжки Рассмотрим сценарий FindAndDelRecord.wsf, с помощью которого можно будет полностью удалить из записной книжки данные о человеке, фамилия которого введена в диалоговом окне (рис. 6.1). Рис. 6.1. Ввод фамилии для удаления Сценарий FindAndDelRecord.wsf реализован в виде WS-файла для того, чтобы можно было внутри JScript-кода воспользоваться функцией InputNameна языке VBScript, которая реализует диалоговое окно с полем ввода, показанное на рис. 6.1: Function InputName 'Вводим фамилию в диалоговом окне InputName = InputBox("Введите фамилию для удаления:", "Записная книжка") End Function Фамилия, которую следует найти и удалить в записной книжке, сохраняется в глобальной переменной LastName: LastName=InputName(); Непосредственно поиск и удаление данных производятся в функции FindAndDelRecord(). Здесь, как и во всех рассмотренных ранее примерах, сначала создается экземпляр XMLDocобъекта DOMDocument, с помощью метода loadзагружается файл book.xml и указатель на корневой элемент сохраняется в переменной Root: XMLDoc = WScript.CreateObject("Msxml.DOMDocument"); XMLDoc.load(PathBook); Root=XMLDoc.documentElement; Для выделения в записной книжке всех фамилий, которые требуется удалить, используется метод selectNodes(). В качестве аргумента этого метода подставляется строка sSelect, которая указывает, что нужно искать расположенные внутри элементов Personэлементы с именем LastNameи значением, которое совпадает со значением переменной LastName. Все найденные элементы помещаются в коллекцию NodeList: //Формируем строку для поиска фамилии sSelect="Person/LastName[text()='"+LastName+"']"; //Создаем коллекцию NodeList всех элементов LastName, //значение которых совпадает со значением переменной LastName NodeList=XMLDoc.documentElement.selectNodes(sSelect); Если найден хотя бы один подходящий элемент LastName, т.е. коллекция NodeListне является пустой, то для каждого такого элемента в цикле forопределяется родительский элемент (в нашем случае это элемент Person) и этот элемент вместе со всеми своими дочерними элементами удаляется с помощью метода removeChild(): for (i=0;i<=NodeList.length-1;i++) { //Определяем родительский элемент (Person) для найденного //элемента LastName Parent=NodeList.item(i).parentNode; //Удаляем элемент Person вместе со всеми его дочерними элементами Root.removeChild(Parent); //Выводим диалоговое окно с сообщением WshShell.Popup("Запись удалена!",0, "Работа с XML-файлом",vbInformation+vbOkOnly); } После удаления всех записей содержимое XML-файла book.xml сохраняется на диске с помощью метода save(): XMLDoc.save(PathBook); Полный текст сценария FindAndDelRecord.wsf приводится в листинге 6.6. Листинг 6.6. Поиск и удаление данных в XML-файле с помощью XML DOM<job id="PhoneBook"> <runtime> <description> Имя: FindAndDelRecord.wsf Описание: Записная книжка (данные в XML-файле book.xml). Поиск и удаление элементов из XML-файла </description> </runtime> <script language="VBScript"> 'Функция возвращает фамилию для удаления Function InputName 'Вводим фамилию в диалоговом окне InputName = InputBox("Введите фамилию для удаления:", "Записная книжка") End Function </script> <script language="JScript"> //Объявляем переменные var WshShell, LastName, //Удаляемая фамилия BasePath, //Путь к текущему каталогу PathBook, //Путь к файлу с данными XMLDoc, //XML-файл с данными NomRec=0, //Счетчик количества записей PersonRec, //Объект для хранения данных об одном человеке PersonArr; //Массив для хранения объектов PersonRec //Инициализируем константы для диалоговых окон var vbYesNo=4,vbQuestion=32,vbInformation=64,vbYes=6,vbOkOnly=0; //Поиск фамилии в записной книжке и удаление всех //реквизитов, относящихся к этой фамилии function FindAndDelRecord() { var Root,sSelect,i,Parent,NodeList; //Создаем объект DOMDocument XMLDoc = WScript.CreateObject("Msxml.DOMDocument"); //Загружаем XML-файл XMLDoc.load(PathBook); //Сохраняем в переменной Root ссылку на корневой элемент //документа Root=XMLDoc.documentElement; //Формируем строку для поиска фамилии sSelect="Person/LastName[text()='"+LastName+"']"; //Создаем коллекцию NodeList всех элементов LastName, //значение которых совпадает со значением переменной LastName NodeList=XMLDoc.documentElement.selectNodes(sSelect); if (NodeList.length==0) //Коллекция NodeList пуста //Выводим диалоговое окно с сообщением WshShell.Popup("Фамилия "+LastName+ " не найдена в записной книжке!",0, "Работа с XML-файлом",vbInformation+vbOkOnly); else { //Требуемая фамилия найдена //Цикл по всем найденным элементам LastName for (i=0;i<=NodeList.length-1;i++) { //Определяем родительский элемент (Person) для найденного //элемента LastName Parent=NodeList.item(i).parentNode; //Удаляем элемент Person вместе со всеми его дочерними элементами Root.removeChild(Parent); //Выводим диалоговое окно с сообщением WshShell.Popup("Запись удалена!",0, "Работа с XML-файлом",vbInformation+vbOkOnly); } //Сохраняем содержимое XML-файла на диске XMLDoc.save(PathBook); } } //Построение путей к файлам function InitPath() { BasePath=WshShell.CurrentDirectory+"\\"; //Путь к файлу с данными PathBook=BasePath+"book.xml"; } //Основная запускная функция function Main() { var Res; //Создаем объект WshShell WshShell = WScript.CreateObject("WScript.Shell"); //Определяем пути к файлам InitPath(); LastName=InputName(); //Запрос на удаление записи Res=WshShell.Popup("Удалить фамилию "+LastName+ " из \n"+PathBook+"?",0, "Работа с XML-файлом",vbQuestion+vbYesNo); if (Res==vbYes) { //Нажата кнопка Да //Ищем в книжке нужную фамилию и удаляем относящуюся к //ней запись FindAndDelRecord(); } } /******************* Начало **********************************/ Main(); /************* Конец *********************************************/ </script> </job> |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|