Теория и практика разработки современных клиентских веб-приложений

Объектная модель DOM XML

Разбить на страницы
Показывать лекцию целиком

Структурный анализ (парсинг) XML

Все современные браузеры имеют встроенные XML анализаторы (парсеры) для чтения и обработки XML. Анализатор считывает XML документ, размещает его в памяти и преобразует в XML DOM объект, доступный для языков программирования. В данной лекции все примеры приведены на JavaScript.

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

Рассмотрим пример загрузки XML объектов (файлов и строк) с помощью XML анализатора Microsoft.

xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.load("timetable.xml");

В первой строке программы создается пустой объект XML документа Microsoft. Далее для предотвращения работы сценария до полной загрузки документа флаг асинхронности устанавливается в "false". В третьей строке содержится инструкция загрузить XML файл "timetable.xml".

В следующем примере происходит загрузка строки с XML кодом для последующего анализа.

xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(txt);

Следует обратить на разницу между методами load() и loadXML() по их назначению.

Замечание. Современные браузеры не допускают междоменные обращения к файлам из соображений безопасности, т.е. сама веб-страница (с программным кодом) и XML файл должны физически находиться на одном сервере. В противном случае браузер выдаст сообщение об ошибке доступа.

Ниже приведены также кроссплатформенные реализации загрузки XML файла и XML строки соответственно.

<html>
<body>
<script type="text/javascript">
try //Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  }
catch(e)
  {
  try //Firefox, Mozilla, Opera, etc.
    {
    xmlDoc=document.implementation.createDocument("","",null);
    }
  catch(e) {alert(e.message)}
  }
try 
  {
  xmlDoc.async=false;
  xmlDoc.load("timetable.xml");
  document.write("xmlDoc is loaded, ready for use");
  }
catch(e) {alert(e.message)}
</script>
</body>
</html>
<html>
<body>
<script type="text/javascript">
text="<timetable>";
text=text+"<lesson>";
text=text+"<timeFrom>08.00</timeFrom>";
text=text+"<subject>Deutsch</subject>";
text=text+"<teacher>Borisova</teacher>";
text=text+"</lesson>";
text=text+"/<timetable>";

try //Internet Explorer
  {
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
  xmlDoc.async="false";
  xmlDoc.loadXML(text);
}
catch(e)
  {
  try //Firefox, Mozilla, Opera, etc.
    {
    parser=new DOMParser();
    xmlDoc=parser.parseFromString(text,"text/xml");
    }
  catch(e) {alert(e.message)}
  }
document.write("xmlDoc is loaded, ready for use");
</script>
</body>
</html>

Программный интерфейс XML DOM

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

Свойства представляют некоторые сущности (например, <day> ), а методы - действия над ними (например, добавить <lesson> ).

В XML DOM используются практически те же свойства и методы, что и в HTML DOM.

Например, результатом выполнения следующего ниже JavaScript кода будет текстовое содержимое элемента <subject> в файле timetable.xml.

txt = xmlDoc.getElementsByTagName("subject")[0].childNodes[0].nodeValue;

Результат: "Deutsch".

В рамках DOM XML возможны 3 способа доступа к узлам:

  • С помощью метода getElementsByTagName(name) . При этом возвращаются все узлы с указанным именем тэга (в виде индексированного списка). Первый элемент в списке имеет нулевой индекс.
  • Путем обхода узлов дерева с использованием циклических конструкций.
  • Путем перемещения по дереву с использованием отношений между узлами.
  • Для определения длины списка узлов используется свойство length.

    Перемещение между узлами дерева

    В XML DOM отношения между узлами определены в виде следующих свойств узлов:

  • parentNode
  • childNodes
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling
  • Характер отношений между узлами представлен на следующем рисунке:

    Игнорирование пустых текстовых узлов

    Firefox и некоторые другие браузеры воспринимают неотображаемые символы как текстовые узлы (в отличие от Internet Explorer ). Такая ситуация приводит к проблемам при использовании свойств firstChild, lastChild, nextSibling, previousSibling. Для того, чтобы игнорировать такие пустые текстовые узлы можно использовать следующий прием:

    function get_nextSibling(n)
    {
    y = n.nextSibling;
    while (y.nodeType!=1)
      {
      y = y.nextSibling;
      }
    return y;
    }

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

    Изменение значения атрибута

    Узлы атрибутов могут принимать текстовые значения. Изменение этого значения реализуется либо через метод setAttribute(), либо через свойство узла атрибута node Value

    Метод setAttribute() изменяет значение существующего атрибута или создает новый атрибут.

    Например:

    xmlDoc = loadXMLDoc("timetable.xml");
    x = xmlDoc.getElementsByTagName('lesson');
    x[0].setAttribute("type","lab");

    Свойство nodeValue можно использовать для изменения значения атрибута узла:

    xmlDoc = loadXMLDoc("timetable.xml");
    x = xmlDoc.getElementsByTagName("lesson")[0];
    y = x.getAttributeNode("type");
    y.nodeValue = "lab";

    Удаление узла из дерева реализуется с помощью метода removeChild():

    xmlDoc=loadXMLDoc("timetable.xml ");
    y = xmlDoc.getElementsByTagName("lesson")[0];
    xmlDoc.documentElement.removeChild(y);

    Свойства объекта Node

    IE: Internet Explorer, F: Firefox, O: Opera, W3C: (Стандарт)

    Свойство Описание IE F O W3C
    baseURI Возвращает абсолютный URI узла Нет 1 Нет Да
    childNodes Возвращает свойство NodeList (список доч.узлов) 5 1 9 Да
    firstChild Возвращает первый дочерний узел 5 1 9 Да
    lastChild Возвращает последний дочерний узел 5 1 9 Да
    localName Возвращает локальную часть имени узла Нет 1 9 Да
    namespaceURI Возвращает URI узла в пространстве имен Нет 1 9 Да
    nextSibling Возвращает следующий дочерний узел 5 1 9 Да
    nodeName Возвращает имя узла в зависимости от типа 5 1 9 Да
    nodeType Возвращает тип узла 5 1 9 Да
    nodeValue Устанавливает или возвращает значение узла в зависимости от типа 5 1 9 Да
    ownerDocument Возвращает корневой элемент (объект document) для узла 5 1 9 Да
    parentNode Возвращает родительский узел 5 1 9 Да
    prefix Устанавливает или возвращает префикс пространства имен узла Нет 1 9 Да
    previousSibling Возвращает непосредственно предшествующий узел 5 1 9 Да
    textContent Устанавливает или возвращает текстовое содержимое узла Нет 1 Нет Да
    xml Возвращает XML код узла 5 Нет Нет Нет

    Методы объекта Node

    Метод Описание IE F O W3C
    appendChild() Добавить новый узел в конец списка дочерних узлов 5 1 9 Да
    cloneNode() Клонирование узла 5 1 9 Да
    compareDocumentPosition() Сравнение позиций двух узлов Нет 1 Нет Да
    getFeature(feature,version) Возвращает объект DOM, реализующий специализированный API Нет Да
    getUserData(key) Возвращает объект, ассоциирующийся с ключем текущего узла. Перед этим объект должен быть ассоциирован с текущим узлом путем вызова setUserData с тем же ключем Нет 1 9 Да
    hasAttributes() Возвращает истинное значение, если узел имеет атрибуты 1 9
    hasChildNodes() Возвращает истинное значение, если узел имеет дочерние узлы 5 1 9 Да
    insertBefore() Вставляет новый узел перед существующим узлом 5 1 9 Да
    isDefaultNamespace(URI) Определяет, является ли указанный namespaceURI значением по умолчанию Нет Да
    isEqualNode() Проверяет равенство двух узлов Нет Нет Нет Да
    isSameNode() Проверяет идентичность двух узлов Нет 1 Нет Да
    isSupported(feature,version) Определяет - поддерживается ли указанная характеристика узлом 9 Да
    removeChild() Удаляет дочерний узел 5 1 9 Да
    replaceChild() Заменяет дочерний узел 5 1 9 Да
    setUserData(key,data,handler) Ассоциирует объект с ключем в узле Нет Да

    SAX парсер

    Альтернативным интерфейсом для обработки XML документов является SAX.

    SAX (Simple API for XML) - прикладной программный интерфейс для парсера с последовательным доступом к XML. Этот интерфейс предоставляет механизм чтения данных из XML документа.

    SAX парсер является поточным и управляемым событиями. Задачей пользователя SAX API заключается в описании методов, вызываемых событиями, возникающими при анализе документа.

    Такими событиями могут быть следующие:

  • текстовый узел;
  • узел элемента XML ;
  • инструкция обработки XML ;
  • комментарий XML.
  • События вызываются появлением как открывающего тэга, так и закрывающего тэга любого из этих элементов документа. Атрибут XML также рассматривается как событие.

    Анализ документа является однонаправленным (т.е. без возвратов по дереву).

    В отличие от DOM формальной спецификации для SAX не существует. В качестве нормативной рассматривается Java реализация SAX.

    Следует отметить следующие достоинства и недостатки SAX.

    Достоинства:

  • Затраты памяти существенно меньше (зависит от максимальной глубины дерева документа и количества атрибутов в узле элемента), чем в случае DOM (требуется хранить в памяти все дерево документа).
  • Скорость работы выше за счет сокращения затрат времени на выделение памяти для элементов дерева в случае DOM.
  • Потоковое чтение данных с диска в случае DOM невозможно. Если для размещения всего документа в памяти недостаточно места, то использование SAX является безальтернативным.
  • Недостатки:

  • Процедура проверки правильности предполагает доступ ко всему документу одновременно.
  • Это также требуется и в случае XSLT преобразования.
  • Структура и представление XML документа

    Если загрузить "чистый" XML документ в веб-браузер, то можно будет увидеть древовидную структуру этого документа:

    (рис 10.1) Вид XML документа в веб-браузере

    В этом как раз и заключается главное отличие между XML и HTML, а именно разделение структуры документа и его представления в браузере. Конкретный вид XML документа описывается отдельно с помощью CSS или XSL.

    CSS и XSL - принципиально разные технологии, имеющие лишь частичное пересечение областей применения. CSS -форматирование применяется к HTML -документу браузером на клиентской стороне, а XSL -преобразование выполняется, как правило, на сервере, после чего результат отправляется браузеру клиента. XSL базируется на XML, благодаря чему XSL более гибок и универсален. У разработчиков имеется возможность использовать средства контроля за корректностью составления стилевых списков (используя схемы XML ).

    С помощью XSL можно преобразовать XML -документ в формат HTML, WML, RTF, PDF, SQL, SWF, а так же в другой XML и XSL документ. XSL указывает как будет оформлен документ, где и каким образом должны размещаться данные.

    Cпецификация XSL состоит из трех частей:

  • XSLT (XSL Transformations) , язык для преобразования XML ;
  • XPath - язык путей и выражений, используемый в XSLT для доступа к отдельным частям XML -документа;
  • XSL-FO (XSL Formatting Objects) , язык для верстки XML.
  • Наиболее распространенным механизмом XSLT преобразований для систем работающих на платформе Microsoft Windows является MSXML ; для систем на основе GNU - xsltproc.

    Для того, чтобы обработать XML документ c помощью XSL, необходимо в XML документе написать следующую инструкцию:

    <?xml version="1.0"?> 
    <?xml-stylesheet type="text/xsl" href="my-style.xsl"?> 
    <root> 
    	< !-- ... -- > 
    </root>

    Объявление XSL

    Корневым элементом, указывающим на то, что документ является XSL таблицей стилей является следующий:

    <xsl:stylesheet>

    или полностью равноценный ему

    <xsl:transform>

    В соответствии с W3C XSLT Рекомендацией корректный способ объявления таблицы стилей XSL выглядит следующим образом:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    или

    <xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    Для того чтобы XSLT элементы, атрибуты и характеристики были доступны в начале документа необходимо объявить пространство имен XSLT:

    xmlns:xsl=http://www.w3.org/1999/XSL/Transform

    указывающее на официальное пространство имен W3C XSLT. При этом также следует указать атрибут version="1.0".

    Реализация преобразования с помощью сценария.

    XSLT преобразование из XML в XHTML выполняемое самими браузерами на основе таблицы стилей XSL является не всегда желательным, поскольку может поддерживаться не всеми браузерами.

    Использование в качестве альтернативы JavaScript позволяет:

  • Выполнять проверку типа браузера
  • Использовать подходящие таблицы стилей в зависимости от типа браузера и потребностей пользователей.
  • Другим решением для браузеров, не поддерживающих XSLT является преобразование XML в XHTML на веб-сервере.

    Пример разметки XML файла

    Возвращаясь к рассмотренному ранее примеру, добавив в XML файл ссылку на XSL файл, получим следующий код разметки:

    <?xml version="1.0" encoding="windows-1251" ?>
    <!DOCTYPE mailbox SYSTEM "mailbox.dtd">
    <?xml-stylesheet href="mailbox.xsl" type="text/xsl" ?>
    
    <mailbox>
     <message uid='1'>
      <body>Проверка почтового ящика</body>
      <head>
        <to>user2@myhp.edu</to>
        <to>user3@myhp.edu</to>
        <from>user1@myhp.edu</from>
        <subject>Test</subject>
        <cc></cc>
        <notify></notify>
      </head>
     </message>
     <message uid='2'>
      <body>Это письмо не является спамом</body>
      <head>
        <to>user2@myhp.edu</to>
        <from>user4@myhp.edu</from>
        <subject>Интересное предложение</subject>
        <notify></notify>
      </head>
     </message>
    </mailbox>

    После загрузки данного документа в веб-браузере его вид кардинально изменится:

    (рис 10.2) Вид XML документа в веб-браузере (добавлены DTD и XSL)

    Содержимое XSL файла mailbox.xsl приводится ниже:

    <?xml version="1.0" encoding="windows-1251"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template match = "mailbox">
        <h2 align="center" color="red">Почтовый ящик</h2>
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match = "message">
        <table align="center" border="0" width="80%" bgcolor="gray">
    	 <tr><td width="20%"><b>From:</b></td><td><xsl:value-of select="head/from"/></td></tr>
    	 <tr>
    	    <td width="20%"> <b>To:</b> </td>
    	    <td> <xsl:for-each select="head/to">
    		 <xsl:apply-templates/>, 
    		 </xsl:for-each>
    	    </td>
    	 </tr>
    	 <tr><td width="20%"><b>Subject:</b></td><td><xsl:value-of select="head/subject"/></td></tr>
    	 <tr><td width="20%"><b>CC</b></td><td><xsl:value-of select="head/cc"/></td></tr>
    	 <tr><td width="20%"><b>Notify</b></td><td><xsl:value-of select="head/notify"/></td></tr>
    	 <tr><td colspan="2">
    		<textarea cols="120%" rows="3"> <xsl:value-of select="body"/> </textarea>
    	 </td></tr>
        </table>
        <br/><hr/><br/>
    </xsl:template>
    
    </xsl:stylesheet>

    XSLT и XPath

    XSLT можно определить следующим образом:

  • XSLT обозначает XSL Transformations.
  • XSLT является самой важной частью XSL преобразования
  • XSLT позволяет преобразовывать один XML в другой XML документ.
  • XSLT использует XPath для перемещения по структуре XML документа.
  • XSLT является W3C рекомендацией с ноября 1999 года.
  • XSLT используется для преобразования XML документа в другой XML документ либо в документ другого распознаваемого браузерами типа, например HTML или XHTML. Обычно XSLT делает это, преобразуя каждый XML элемент в соответствующий ему (X)HTML элемент.

    С помощью XSLT можно добавлять или удалять элементы и атрибуты в результирующем документе. Также возможна перегруппировка и сортировка элементов, фильтрация элементов при отображении и многое другое.

    В результате применения таблицы стилей XSLT, состоящей из набора шаблонов, к XML -документу (исходное дерево) образуется конечное дерево, которое может быть другой XML - структурой, HTML - документом или обычным текстом. Правила выбора данных из исходного дерева записываются на языке запросов XPath. XSLT применяется в основном в веб-программировании и для генерации отчётов.

    В процессе преобразования XSLT использует XPath для поиска частей исходного документа, соответствующих одному или более заданных шаблонов. Когда соответствие найдено XSLT преобразует найденную часть исходного документа в соответствующую часть результирующего документа.

    Подавляющее большинство браузеров имеют поддержку XML и XSLT.

    Internet Explorer

    Начиная с 6 версии, Internet Explorer поддерживает XML, пространства имен, CSS, XSLT и XPath. Версия 5 не совместима с официальной W3C XSL Рекомендацией.

    Mozilla Firefox

    Начиная с версии 1.0.2, Firefox поддерживает XML и XSLT (CSS) .

    Mozilla

    Mozilla содержит Expat for XML парсер поддерживает отображение XML+CSS. Также имеет поддержка пространства имен. Реализует XSLT преобразования.

    Netscape

    Начиная с версии 8, Netscape использует в качестве ядра Mozilla, и поэтому имеет такую же поддержку XML/XSLT.

    Opera

    Начиная с версии 9, Opera поддерживает XML и XSLT (CSS) . Версия 8 поддерживает только XML+CSS.

    Благодаря XSLT реализуется отделение данных от их представления в Рамках парадигмы MVC (Model-view-controller) .

    XPath (XML Path Language) - язык запросов к элементам XML -документа. XPath был разработан для организации доступа к частям документа XML в файлах трансформации XSLT и является стандартом консорциума W3C. В языке XPath используется компактный синтаксис, отличный от принятого в XML. Начиная с версии 2.0, XPath является составной частью языка XQuery. XPath призван помочь обходить всевозможные деревья, получать необходимые элементы из другой ветви относительно точки обхода, распознавать предков, потомков, атрибуты элементов. Это полноценный язык навигации по дереву.

    Для нахождения элемента(ов) в дереве документа используются пути адресации.

    Каждый шаг адресации состоит из трех частей:

  • оси, например child:: ;
  • условия проверки узлов, например имена элементов документа body, html;
  • предиката, например attribute::class.
  • Дополнением к ядру языка является набор функций, которые делятся на 5 групп: системные функции, функции с множествами, строковые функции, логические функции, числовые функции.

    XSL-FO

    XSL-FO (eXtensible Markup Language Formatting Objects) - рекомендованный W3C язык разметки предпечатных материалов. По-сути, XSL-FO - это унифицированный язык представления. Он не имеет семантической разметки (как в HTML ) и сохраняет все данные документа внутри себя (в отличие от CSS, который модифицирует представление по умолчанию для внешнего HTML или XML -документа) .

    В результате применения XSLT - преобразования к исходному XML документу получается его описание на языке XSL-FO. FO - процессор конвертирует XSL-FO -документ в какой-либо читаемый и/или печатаемый формат. Наиболее часто используется преобразование в PDF либо PS ; некоторые FO -процессоры могут давать на выходе RTF -файлы либо просто показывать документ в окне.

    XQuery

    XQuery - язык запросов, разработанный для обработки данных в формате XML.

    В настoящее время рабочими группами консорциума W3C ведутся работы по развитию этого стандарта данного языка, с добавлением выражений для свободного поиска по тексту и для внесения изменений в XML документы и базы данных, а также для процедурных операций.

    В рамках стандарта SQL:2006 разработаны механизмы для встраивания XQuery -запросов непосредственно в SQL -запросы.

    Страницы:

    Структурный анализ (парсинг) XML

    Все современные браузеры имеют встроенные XML анализаторы (парсеры) для чтения и обработки XML. Анализатор считывает XML документ, размещает его в памяти и преобразует в XML DOM объект, доступный для языков программирования. В данной лекции все примеры приведены на JavaScript.

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

    Рассмотрим пример загрузки XML объектов (файлов и строк) с помощью XML анализатора Microsoft.

    xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async="false";
    xmlDoc.load("timetable.xml");

    В первой строке программы создается пустой объект XML документа Microsoft. Далее для предотвращения работы сценария до полной загрузки документа флаг асинхронности устанавливается в "false". В третьей строке содержится инструкция загрузить XML файл "timetable.xml".

    В следующем примере происходит загрузка строки с XML кодом для последующего анализа.

    xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async="false";
    xmlDoc.loadXML(txt);

    Следует обратить на разницу между методами load() и loadXML() по их назначению.

    Замечание. Современные браузеры не допускают междоменные обращения к файлам из соображений безопасности, т.е. сама веб-страница (с программным кодом) и XML файл должны физически находиться на одном сервере. В противном случае браузер выдаст сообщение об ошибке доступа.

    Ниже приведены также кроссплатформенные реализации загрузки XML файла и XML строки соответственно.

    <html>
    <body>
    <script type="text/javascript">
    try //Internet Explorer
      {
      xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
      }
    catch(e)
      {
      try //Firefox, Mozilla, Opera, etc.
        {
        xmlDoc=document.implementation.createDocument("","",null);
        }
      catch(e) {alert(e.message)}
      }
    try 
      {
      xmlDoc.async=false;
      xmlDoc.load("timetable.xml");
      document.write("xmlDoc is loaded, ready for use");
      }
    catch(e) {alert(e.message)}
    </script>
    </body>
    </html>
    <html>
    <body>
    <script type="text/javascript">
    text="<timetable>";
    text=text+"<lesson>";
    text=text+"<timeFrom>08.00</timeFrom>";
    text=text+"<subject>Deutsch</subject>";
    text=text+"<teacher>Borisova</teacher>";
    text=text+"</lesson>";
    text=text+"/<timetable>";
    
    try //Internet Explorer
      {
      xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
      xmlDoc.async="false";
      xmlDoc.loadXML(text);
    }
    catch(e)
      {
      try //Firefox, Mozilla, Opera, etc.
        {
        parser=new DOMParser();
        xmlDoc=parser.parseFromString(text,"text/xml");
        }
      catch(e) {alert(e.message)}
      }
    document.write("xmlDoc is loaded, ready for use");
    </script>
    </body>
    </html>

    Программный интерфейс XML DOM

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

    Свойства представляют некоторые сущности (например, <day> ), а методы - действия над ними (например, добавить <lesson> ).

    В XML DOM используются практически те же свойства и методы, что и в HTML DOM.

    Например, результатом выполнения следующего ниже JavaScript кода будет текстовое содержимое элемента <subject> в файле timetable.xml.

    txt = xmlDoc.getElementsByTagName("subject")[0].childNodes[0].nodeValue;

    Результат: "Deutsch".

    В рамках DOM XML возможны 3 способа доступа к узлам:

  • С помощью метода getElementsByTagName(name) . При этом возвращаются все узлы с указанным именем тэга (в виде индексированного списка). Первый элемент в списке имеет нулевой индекс.
  • Путем обхода узлов дерева с использованием циклических конструкций.
  • Путем перемещения по дереву с использованием отношений между узлами.
  • Для определения длины списка узлов используется свойство length.

    Перемещение между узлами дерева

    В XML DOM отношения между узлами определены в виде следующих свойств узлов:

  • parentNode
  • childNodes
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling
  • Характер отношений между узлами представлен на следующем рисунке:

    Игнорирование пустых текстовых узлов

    Firefox и некоторые другие браузеры воспринимают неотображаемые символы как текстовые узлы (в отличие от Internet Explorer ). Такая ситуация приводит к проблемам при использовании свойств firstChild, lastChild, nextSibling, previousSibling. Для того, чтобы игнорировать такие пустые текстовые узлы можно использовать следующий прием:

    function get_nextSibling(n)
    {
    y = n.nextSibling;
    while (y.nodeType!=1)
      {
      y = y.nextSibling;
      }
    return y;
    }

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

    Изменение значения атрибута

    Узлы атрибутов могут принимать текстовые значения. Изменение этого значения реализуется либо через метод setAttribute(), либо через свойство узла атрибута node Value

    Метод setAttribute() изменяет значение существующего атрибута или создает новый атрибут.

    Например:

    xmlDoc = loadXMLDoc("timetable.xml");
    x = xmlDoc.getElementsByTagName('lesson');
    x[0].setAttribute("type","lab");

    Свойство nodeValue можно использовать для изменения значения атрибута узла:

    xmlDoc = loadXMLDoc("timetable.xml");
    x = xmlDoc.getElementsByTagName("lesson")[0];
    y = x.getAttributeNode("type");
    y.nodeValue = "lab";

    Удаление узла из дерева реализуется с помощью метода removeChild():

    xmlDoc=loadXMLDoc("timetable.xml ");
    y = xmlDoc.getElementsByTagName("lesson")[0];
    xmlDoc.documentElement.removeChild(y);

    Свойства объекта Node

    IE: Internet Explorer, F: Firefox, O: Opera, W3C: (Стандарт)

    Свойство Описание IE F O W3C
    baseURI Возвращает абсолютный URI узла Нет 1 Нет Да
    childNodes Возвращает свойство NodeList (список доч.узлов) 5 1 9 Да
    firstChild Возвращает первый дочерний узел 5 1 9 Да
    lastChild Возвращает последний дочерний узел 5 1 9 Да
    localName Возвращает локальную часть имени узла Нет 1 9 Да
    namespaceURI Возвращает URI узла в пространстве имен Нет 1 9 Да
    nextSibling Возвращает следующий дочерний узел 5 1 9 Да
    nodeName Возвращает имя узла в зависимости от типа 5 1 9 Да
    nodeType Возвращает тип узла 5 1 9 Да
    nodeValue Устанавливает или возвращает значение узла в зависимости от типа 5 1 9 Да
    ownerDocument Возвращает корневой элемент (объект document) для узла 5 1 9 Да
    parentNode Возвращает родительский узел 5 1 9 Да
    prefix Устанавливает или возвращает префикс пространства имен узла Нет 1 9 Да
    previousSibling Возвращает непосредственно предшествующий узел 5 1 9 Да
    textContent Устанавливает или возвращает текстовое содержимое узла Нет 1 Нет Да
    xml Возвращает XML код узла 5 Нет Нет Нет

    Методы объекта Node

    Метод Описание IE F O W3C
    appendChild() Добавить новый узел в конец списка дочерних узлов 5 1 9 Да
    cloneNode() Клонирование узла 5 1 9 Да
    compareDocumentPosition() Сравнение позиций двух узлов Нет 1 Нет Да
    getFeature(feature,version) Возвращает объект DOM, реализующий специализированный API Нет Да
    getUserData(key) Возвращает объект, ассоциирующийся с ключем текущего узла. Перед этим объект должен быть ассоциирован с текущим узлом путем вызова setUserData с тем же ключем Нет 1 9 Да
    hasAttributes() Возвращает истинное значение, если узел имеет атрибуты 1 9
    hasChildNodes() Возвращает истинное значение, если узел имеет дочерние узлы 5 1 9 Да
    insertBefore() Вставляет новый узел перед существующим узлом 5 1 9 Да
    isDefaultNamespace(URI) Определяет, является ли указанный namespaceURI значением по умолчанию Нет Да
    isEqualNode() Проверяет равенство двух узлов Нет Нет Нет Да
    isSameNode() Проверяет идентичность двух узлов Нет 1 Нет Да
    isSupported(feature,version) Определяет - поддерживается ли указанная характеристика узлом 9 Да
    removeChild() Удаляет дочерний узел 5 1 9 Да
    replaceChild() Заменяет дочерний узел 5 1 9 Да
    setUserData(key,data,handler) Ассоциирует объект с ключем в узле Нет Да

    SAX парсер

    Альтернативным интерфейсом для обработки XML документов является SAX.

    SAX (Simple API for XML) - прикладной программный интерфейс для парсера с последовательным доступом к XML. Этот интерфейс предоставляет механизм чтения данных из XML документа.

    SAX парсер является поточным и управляемым событиями. Задачей пользователя SAX API заключается в описании методов, вызываемых событиями, возникающими при анализе документа.

    Такими событиями могут быть следующие:

  • текстовый узел;
  • узел элемента XML ;
  • инструкция обработки XML ;
  • комментарий XML.
  • События вызываются появлением как открывающего тэга, так и закрывающего тэга любого из этих элементов документа. Атрибут XML также рассматривается как событие.

    Анализ документа является однонаправленным (т.е. без возвратов по дереву).

    В отличие от DOM формальной спецификации для SAX не существует. В качестве нормативной рассматривается Java реализация SAX.

    Следует отметить следующие достоинства и недостатки SAX.

    Достоинства:

  • Затраты памяти существенно меньше (зависит от максимальной глубины дерева документа и количества атрибутов в узле элемента), чем в случае DOM (требуется хранить в памяти все дерево документа).
  • Скорость работы выше за счет сокращения затрат времени на выделение памяти для элементов дерева в случае DOM.
  • Потоковое чтение данных с диска в случае DOM невозможно. Если для размещения всего документа в памяти недостаточно места, то использование SAX является безальтернативным.
  • Недостатки:

  • Процедура проверки правильности предполагает доступ ко всему документу одновременно.
  • Это также требуется и в случае XSLT преобразования.
  • Структура и представление XML документа

    Если загрузить "чистый" XML документ в веб-браузер, то можно будет увидеть древовидную структуру этого документа:

    (рис 10.1) Вид XML документа в веб-браузере

    В этом как раз и заключается главное отличие между XML и HTML, а именно разделение структуры документа и его представления в браузере. Конкретный вид XML документа описывается отдельно с помощью CSS или XSL.

    CSS и XSL - принципиально разные технологии, имеющие лишь частичное пересечение областей применения. CSS -форматирование применяется к HTML -документу браузером на клиентской стороне, а XSL -преобразование выполняется, как правило, на сервере, после чего результат отправляется браузеру клиента. XSL базируется на XML, благодаря чему XSL более гибок и универсален. У разработчиков имеется возможность использовать средства контроля за корректностью составления стилевых списков (используя схемы XML ).

    С помощью XSL можно преобразовать XML -документ в формат HTML, WML, RTF, PDF, SQL, SWF, а так же в другой XML и XSL документ. XSL указывает как будет оформлен документ, где и каким образом должны размещаться данные.

    Cпецификация XSL состоит из трех частей:

  • XSLT (XSL Transformations) , язык для преобразования XML ;
  • XPath - язык путей и выражений, используемый в XSLT для доступа к отдельным частям XML -документа;
  • XSL-FO (XSL Formatting Objects) , язык для верстки XML.
  • Наиболее распространенным механизмом XSLT преобразований для систем работающих на платформе Microsoft Windows является MSXML ; для систем на основе GNU - xsltproc.

    Для того, чтобы обработать XML документ c помощью XSL, необходимо в XML документе написать следующую инструкцию:

    <?xml version="1.0"?> 
    <?xml-stylesheet type="text/xsl" href="my-style.xsl"?> 
    <root> 
    	< !-- ... -- > 
    </root>

    Объявление XSL

    Корневым элементом, указывающим на то, что документ является XSL таблицей стилей является следующий:

    <xsl:stylesheet>

    или полностью равноценный ему

    <xsl:transform>

    В соответствии с W3C XSLT Рекомендацией корректный способ объявления таблицы стилей XSL выглядит следующим образом:

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    или

    <xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    Для того чтобы XSLT элементы, атрибуты и характеристики были доступны в начале документа необходимо объявить пространство имен XSLT:

    xmlns:xsl=http://www.w3.org/1999/XSL/Transform

    указывающее на официальное пространство имен W3C XSLT. При этом также следует указать атрибут version="1.0".

    Реализация преобразования с помощью сценария.

    XSLT преобразование из XML в XHTML выполняемое самими браузерами на основе таблицы стилей XSL является не всегда желательным, поскольку может поддерживаться не всеми браузерами.

    Использование в качестве альтернативы JavaScript позволяет:

  • Выполнять проверку типа браузера
  • Использовать подходящие таблицы стилей в зависимости от типа браузера и потребностей пользователей.
  • Другим решением для браузеров, не поддерживающих XSLT является преобразование XML в XHTML на веб-сервере.

    Пример разметки XML файла

    Возвращаясь к рассмотренному ранее примеру, добавив в XML файл ссылку на XSL файл, получим следующий код разметки:

    <?xml version="1.0" encoding="windows-1251" ?>
    <!DOCTYPE mailbox SYSTEM "mailbox.dtd">
    <?xml-stylesheet href="mailbox.xsl" type="text/xsl" ?>
    
    <mailbox>
     <message uid='1'>
      <body>Проверка почтового ящика</body>
      <head>
        <to>user2@myhp.edu</to>
        <to>user3@myhp.edu</to>
        <from>user1@myhp.edu</from>
        <subject>Test</subject>
        <cc></cc>
        <notify></notify>
      </head>
     </message>
     <message uid='2'>
      <body>Это письмо не является спамом</body>
      <head>
        <to>user2@myhp.edu</to>
        <from>user4@myhp.edu</from>
        <subject>Интересное предложение</subject>
        <notify></notify>
      </head>
     </message>
    </mailbox>

    После загрузки данного документа в веб-браузере его вид кардинально изменится:

    (рис 10.2) Вид XML документа в веб-браузере (добавлены DTD и XSL)

    Содержимое XSL файла mailbox.xsl приводится ниже:

    <?xml version="1.0" encoding="windows-1251"?> 
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template match = "mailbox">
        <h2 align="center" color="red">Почтовый ящик</h2>
        <xsl:apply-templates/>
    </xsl:template>
    
    <xsl:template match = "message">
        <table align="center" border="0" width="80%" bgcolor="gray">
    	 <tr><td width="20%"><b>From:</b></td><td><xsl:value-of select="head/from"/></td></tr>
    	 <tr>
    	    <td width="20%"> <b>To:</b> </td>
    	    <td> <xsl:for-each select="head/to">
    		 <xsl:apply-templates/>, 
    		 </xsl:for-each>
    	    </td>
    	 </tr>
    	 <tr><td width="20%"><b>Subject:</b></td><td><xsl:value-of select="head/subject"/></td></tr>
    	 <tr><td width="20%"><b>CC</b></td><td><xsl:value-of select="head/cc"/></td></tr>
    	 <tr><td width="20%"><b>Notify</b></td><td><xsl:value-of select="head/notify"/></td></tr>
    	 <tr><td colspan="2">
    		<textarea cols="120%" rows="3"> <xsl:value-of select="body"/> </textarea>
    	 </td></tr>
        </table>
        <br/><hr/><br/>
    </xsl:template>
    
    </xsl:stylesheet>

    XSLT и XPath

    XSLT можно определить следующим образом:

  • XSLT обозначает XSL Transformations.
  • XSLT является самой важной частью XSL преобразования
  • XSLT позволяет преобразовывать один XML в другой XML документ.
  • XSLT использует XPath для перемещения по структуре XML документа.
  • XSLT является W3C рекомендацией с ноября 1999 года.
  • XSLT используется для преобразования XML документа в другой XML документ либо в документ другого распознаваемого браузерами типа, например HTML или XHTML. Обычно XSLT делает это, преобразуя каждый XML элемент в соответствующий ему (X)HTML элемент.

    С помощью XSLT можно добавлять или удалять элементы и атрибуты в результирующем документе. Также возможна перегруппировка и сортировка элементов, фильтрация элементов при отображении и многое другое.

    В результате применения таблицы стилей XSLT, состоящей из набора шаблонов, к XML -документу (исходное дерево) образуется конечное дерево, которое может быть другой XML - структурой, HTML - документом или обычным текстом. Правила выбора данных из исходного дерева записываются на языке запросов XPath. XSLT применяется в основном в веб-программировании и для генерации отчётов.

    В процессе преобразования XSLT использует XPath для поиска частей исходного документа, соответствующих одному или более заданных шаблонов. Когда соответствие найдено XSLT преобразует найденную часть исходного документа в соответствующую часть результирующего документа.

    Подавляющее большинство браузеров имеют поддержку XML и XSLT.

    Internet Explorer

    Начиная с 6 версии, Internet Explorer поддерживает XML, пространства имен, CSS, XSLT и XPath. Версия 5 не совместима с официальной W3C XSL Рекомендацией.

    Mozilla Firefox

    Начиная с версии 1.0.2, Firefox поддерживает XML и XSLT (CSS) .

    Mozilla

    Mozilla содержит Expat for XML парсер поддерживает отображение XML+CSS. Также имеет поддержка пространства имен. Реализует XSLT преобразования.

    Netscape

    Начиная с версии 8, Netscape использует в качестве ядра Mozilla, и поэтому имеет такую же поддержку XML/XSLT.

    Opera

    Начиная с версии 9, Opera поддерживает XML и XSLT (CSS) . Версия 8 поддерживает только XML+CSS.

    Благодаря XSLT реализуется отделение данных от их представления в Рамках парадигмы MVC (Model-view-controller) .

    XPath (XML Path Language) - язык запросов к элементам XML -документа. XPath был разработан для организации доступа к частям документа XML в файлах трансформации XSLT и является стандартом консорциума W3C. В языке XPath используется компактный синтаксис, отличный от принятого в XML. Начиная с версии 2.0, XPath является составной частью языка XQuery. XPath призван помочь обходить всевозможные деревья, получать необходимые элементы из другой ветви относительно точки обхода, распознавать предков, потомков, атрибуты элементов. Это полноценный язык навигации по дереву.

    Для нахождения элемента(ов) в дереве документа используются пути адресации.

    Каждый шаг адресации состоит из трех частей:

  • оси, например child:: ;
  • условия проверки узлов, например имена элементов документа body, html;
  • предиката, например attribute::class.
  • Дополнением к ядру языка является набор функций, которые делятся на 5 групп: системные функции, функции с множествами, строковые функции, логические функции, числовые функции.

    XSL-FO

    XSL-FO (eXtensible Markup Language Formatting Objects) - рекомендованный W3C язык разметки предпечатных материалов. По-сути, XSL-FO - это унифицированный язык представления. Он не имеет семантической разметки (как в HTML ) и сохраняет все данные документа внутри себя (в отличие от CSS, который модифицирует представление по умолчанию для внешнего HTML или XML -документа) .

    В результате применения XSLT - преобразования к исходному XML документу получается его описание на языке XSL-FO. FO - процессор конвертирует XSL-FO -документ в какой-либо читаемый и/или печатаемый формат. Наиболее часто используется преобразование в PDF либо PS ; некоторые FO -процессоры могут давать на выходе RTF -файлы либо просто показывать документ в окне.

    XQuery

    XQuery - язык запросов, разработанный для обработки данных в формате XML.

    В настoящее время рабочими группами консорциума W3C ведутся работы по развитию этого стандарта данного языка, с добавлением выражений для свободного поиска по тексту и для внесения изменений в XML документы и базы данных, а также для процедурных операций.

    В рамках стандарта SQL:2006 разработаны механизмы для встраивания XQuery -запросов непосредственно в SQL -запросы.

    Вернуться к учебному плану