Онлайн библиотека PLAM.RU


  • Записная книжка в формате XML
  • Просмотр XML-файла с помощью объектной модели Internet Explorer 4.0
  • Описание объектной модели
  • Пример сценария
  • Использование XML DOM для просмотра и изменения ХМL-файла
  • Описание модели XML DOM
  • Просмотр содержимого записной книжки
  • Добавление информации в записную книжку
  • Поиск и удаление записи из книжки 
  • Глава 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-формате

    Тег Значение
    <PhoneList>
    Корневой тег, обозначает начало записной книжки
    <Person>
    Обозначает начало новой записи в книжке
    <LastName>
    Фамилия человека
    <Name>
    Имя
    <Phone>
    Телефон
    <Street>
    Улица
    <House>
    Дом
    <App>
    Квартира
    <Note>
    Замечания

    Иерархия элементов из таблицы 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.

    Замечание

    Как отмечено в документации MSDN, эта объектная модель является устаревшей и должна быть заменена моделью XML DOM (XML Document Object Model), которая является стандартом корпорации W3C. Однако последняя на момент написания книги версия Internet Explorer 6.0 поддерживает обе эти модели для разбора XML-файлов.

    Описание объектной модели

    При рассмотрении объектной модели MSXML данные, которые хранятся в XML-файле, удобно представлять в виде иерархического дерева, имеющего один корневой элемент и множество дочерних элементов различного уровня вложенности.

    Для анализа содержимого XML-файла используются три объекта:

    XML Document
    (объект для работы с XML-документом в целом),
    XML Element
    (отвечает за работу с каждым из элементов XML-файла) и
    Element Collection
    (коллекция XML-элементов, доступ к которым при помощи метода
    item()
    возможен по имени или порядковому номеру).

    Полный набор свойств и методов этих трех объектов мы рассматривать не будем; в табл. 6.2 и 6.3 приведено описание нескольких основных свойств объектов

    XML Document
    и
    XML Element
    , некоторые из них понадобятся нам в дальнейшем при составлении сценария на языке JScript для просмотра записной книжки.


    Таблица 6.2. Свойства объекта

    XML Document

    Свойство Описание
    URL
    Задает или возвращает путь к обрабатываемому документу
    root
    Содержит корневой элемент XML-документа, Свойство доступно только для чтения
    charset
    Возвращает или устанавливает название текущей кодировочной таблицы
    version
    Содержит номер версии XML. Свойство доступно только для чтения

    Таблица 6.3. Свойства объекта

    XML Element

    Свойство Описание
    children
    Содержит коллекцию дочерних элементов
    tagName
    Содержит имя тега. Свойство доступно для чтения и записи
    text
    Возвращает текстовое содержимое элементов и комментариев
    parent
    Возвращает указатель на родительский элемент. Ссылки на родительский элемент имеют все элементы, за исключением корневого
    type
    Возвращает тип элемента: 0 — элемент, 1 — текст, 2 — комментарий, 3 — Document, 4 — DTD

    Пример сценария

    С помощью приведенного ниже сценария 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. Свойства и методы объекта

    DOMDocument

    Название Тип Описание
    childNodes
    Свойство Содержит коллекцию всех узлов документа. Свойство доступно только для чтения
    documentElement
    Свойство Содержит ссылку на корневой элемент документа. Свойство доступно как для чтения, так и для записи
    getElementsByTagName(tagName)
    Метод Возвращает коллекцию всех элементов в документе, имеющих имя, которое задается параметром
    tagName
    hasChildNodes()
    Метод Возвращает
    true
    , если в документе есть элементы. В противном случае возвращает
    false
    load(url)
    Метод Загружает XML-документ из файла, путь к которому задан параметром
    url
    loadXML(xmlString)
    Метод Загружает XML-документ, содержимое которого содержится в строке
    xmlString
    url
    Свойство Содержит путь к загруженному XML-документу. Для того чтобы изменить это свойство, нужно заново загрузить документ с помощью метода
    load

    Таблица 6.5. Свойства объекта

    XMLDOMNode

    Название Описание
    attributes
    Содержит список атрибутов узла. Свойство доступно только для чтения
    childNodes
    Содержит коллекцию всех узлов, которые являются дочерними по отношению к данному узлу. Свойство доступно только для чтения
    firstChild
    Содержит ссылку на первый дочерний узел. Свойство доступно только для чтения
    lastChild
    Содержит ссылку на последний дочерний узел. Свойство доступно только для чтения
    nodeName
    Содержит имя узла. Свойство доступно только для чтения
    parentNode
    Содержит ссылку на родительский узел (для тех узлов, которые имеют родительский элемент). Свойство доступно только для чтения
    text
    Возвращает или устанавливает текстовое содержимое узла

    Таблица 6.6. Методы объекта

    XMLDOMNode

    Название Описание
    appendChild(NewElem)
    Добавляет новый элемент
    NewElem
    в качестве последнего дочернего элемента. В качестве результата возвращает ссылку на добавленный узел
    cloneNode(deep)
    Создает новый узел, который является точной копией текущего узла. Параметр
    deep
    это логическая константа, которая указывает, нужно ли при создании нового узла копировать дочерние узлы текущего элемента
    (deep=true)
    , либо этого делать не следует
    (deep=true)
    hasChildNodes()
    Возвращает
    true
    , если у узла есть дочерние элементы. В противном случае возвращает
    false
    removeChild(OldElem)
    Удаляет дочерний элемент, ссылка на который содержится в параметре
    OldElem
    replaceChild(OldElem, NewElem)
    Заменяет элемент, ссылка на который содержится в параметре
    OldElem
    , на элемент, ссылка на который содержится в параметре
    NewElem
    selectNodes(patternString)
    Производит поиск дочерних элементов, содержимое которых удовлетворяет шаблону поиска
    patternString
    . В результате возвращает объект
    XMLDOMNodeList
    , содержащий коллекцию всех найденных узлов
    selectSingleNode(patternString)
    Производит поиск первого дочернего элемента, содержимое которого удовлетворяет шаблону поиска
    patternString
    . В случае удачного поиска возвращает ссылку на найденный элемент, в противном случае возвращает
    Null
     

    Просмотр содержимого записной книжки

    Для того чтобы использовать схему 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>









    Главная | Контакты | Нашёл ошибку | Прислать материал | Добавить в избранное

    Все материалы представлены для ознакомления и принадлежат их авторам.