скрыть

скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Google  
 

Использование XML в среде Delphi



Автор: А.Календарев

Использование СOM в среде Delphi

Последнее время много внимания уделяется построение систем электронного бизнеса, или как их еще назыают - B2B (business to business). Учитывая рекомендации по построению обменных потоковых систем координирующего интернет-технологий органа - WWW Consortium: акцент сделан в сторону XML-технологий и построение систем обмена XML-документами.

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

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

Во всех системах обмен, как правило, строится по одинаковой схеме, с использованием HTTP запросов. В качестве протокола защиты информации применяется протокол SSL (но это отдельная тема).

Один из возможных вариантов обработки XML сообщения является построение BIN/CGI (ISAPI)-приложений или COM (серверных) компонент, формирующих или обрабатывающих XML-документы.

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

Один из наиболее эффективных вариантов реализации - использование существующего XML-парсера, поддерживающего DOM модель. Такой парсер является дистрибутивной поставкой Win`98 или составной частью IE 4,7 и выше (для Win`95) и представляет COM сервер, находящийся в библиотеке msxml.dll.

Модель компонентных объектов (COM) - представляет инкапсулированные данные и методы в единую сущность и способ доступа к ним через систему интерфейсов. Средствами Delphi достаточно просто осуществить доступ к классам COM-объекта (в одном COM-сервере может быть включено несколько классов). Доступ к объектам осуществляется путем инициализации экземпляра класса через систему интерфейсов. Описание интерфейсов осуществляется языком определения интерфейсов (IDL), которое возможно осуществить средствами среды автоматически.

Средствами Delphi осуществляется импорт из COM-сервера msxml.dll, строится файлы описания интерфейса IDL и файл бинарноого описания типов библиотеки - TLB. Данная операция осуществляется через системное меню: Project | Type Library Import… (рис 1). Далее появляется диалоговое окно (рис 2), в котором необходимо выбрать COM-объект (в нашем случае объект зарегистрирован под именем "Microsoft.XMLDom (Version 2.0)" ) и создать TLB-файл (кнопка Create Unit). Используя TLB-файл, среда генерирует "паскалевский" файл описания COM-сервера - MSXML_TLB.pas

импорт TypeLibrary (картинка меню) Диалоговое окно  импорта TypeLibrary
Рис 1 Рис 2

В файле MSXML_TLB.pas описаны все интерфейсы, константы и соклассы COM-сервера.

Для доступа к объектам COM-элемента, необходимо в директиве USES добавить имя файла описания библиотеки (MSXML_TLB.pas). Ниже представлена простейшая программа, использующая DOM стандартный анализатор msxml.dll, которая загружает XML-документ и отображает его в элементе текстового поля Memo1.

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  OleServer, MSXML_TLB, StdCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: Tobject);
var
  coDoc: CoDOMDocument;
  / * объявление сокласса объекта DOMDocument;
  * /
  var
  Doc: IXMLDOMDocument;
  / * класс, согласованный с интерфейсом IDOMDocument;
  * /

begin
  Doc := coDoc.Create;
  / * создание экземпляра объекта DOMDocument;
  * /
    Doc.load('data.xml');
  / * вызов метода Load экземпляра объекта DOMDocument;
  * /
    Memo1.Text := Doc.xml;
  / * доступ к свойстве xml экземпляра объекта DOMDocument;
  * /
end;

end.
Концепция DOM - объектная модель документа

Каждый XML документ представляется в виде набора множества объектов (классов), с помощью которых возможен доступ к отдельным элементам (полям объекта). DOM - интерфейс описывает доступ как к простым объектам типа DOMString или CharacterData, так и к частям или отдельным элементам XML документа: DOMFragmentElement, DOMNode, DOMElement.

Ниже приведены самые важные свойства и методы объектов XMLDOMDocument, XMLDOMNode, XMLDOMNodeList. Необходимо отметить, что представленные ниже методы и функции объектов DOM модели (Document Object Model) используются Microsoft XML-анализатором msxml.dll и несколько шире, чем утвержденная W3C Консорциумом DOM модель.

Более полное описание интерфейса DOM объектов можно найти на www.msdn.microsoft.com/xml

Объект XMLDOMDocument
Представляет верхний уровень объектной иерархии и содержит методы для работы с документом: его загрузки, анализа, создания в нем элементов, атрибутов, комментариев и т.д. .
Свойства
Async Свойство идентифицирующее текущий режим обработки
ParseError Возвращает ссылку на объект обработки ошибки XMLDOMParseError
validateOnParse Включение - выключение верификации документа.
url Возвращает URL документа
documentElement Содержит ссылку на корневой элемент документа в виде объекта XMLDOMElement.
Методы
load(url)
loadXML(xmlString)
Загружает XML документ,
save(objTarget) Сохраняет XML документ в файле
abort Прерывание процесса загрузки и обработки документа.
createAttribute (name) Создает для текущего элемента новый атрибут с указанным именем.
createNode(Type, name, nameSpaceURI) Создает узел указанного типа и названия
createElement(tagName) Создает элемент документа с указанным названием.
createTextNode(data) Создает текст внутри документа
getElementsByTagName(tagname) Возвращает ссылку на коллекцию элементов документа с заданным именем
nodeFromID(idString) Поиск элемента по идентификатору

Объект XMLDOMNode
Объект XMLDOMNode, реализующий базовый DOM интерфейс Node , предназначен для манипулирования с отдельным узлом дерева документа. Его свойства и методы позволяют получать и изменять полную информацию о текущем узле - его тип, название, полное название, его содержимое, список дочерних элементов и т.д.
Свойства
nodeName, baseName Возвращает название текущего узла.
prefix Возвращает Namespace префикс.
dataType Определяет тип содержимого текущего узла
nodeType, nodeTypeString Возвращает тип текущего узла:
attributes Возвращает список атрибутов текущего узла в виде коллекции XMLDOMNamedNodeMap.
text Возвращает содержимое текущего поддерева в виде текста
xml Возвращает XML-представление текущего поддерева.
nodeValue Возвращает содержимое текущего узла.
childNodes Возвращает список дочерних элементов в виде XMLDOMNodeList.
firstChild, lastChild Возвращает первый/последний дочерний элемент
previousSibling ,nextSibling Возвращает предыдущий /следующий сестринский элемент.
parentNode Содержит ссылку на родительский элемент.
ownerDocument Возвращает указатель на документ, в котором находится текущий узел.
Методы
appendChild(newChild) Добавляет текущему узлу новый дочерний элемент.
insertBefore(newChild, refChild) Вставляет дочерний узел, располагая его в текущем поддереве "левее" узла, указанного параметром refChild.
cloneNode (deep) Создание копии текущего элемента.
getAttribute (name)
getAttributeNode (name)
setAttribute(name, value)
setAttributeNode(XMLDOMAttribute)
Доступ к атрибутам (создание, чтение, запись) объекта. Name - имя аттрибута, value - его значение. Возращает значение объект XMLDOMAttribute.
replaceChild(newChild, oldChild) removeChild(oldChild) Замена объекта oldChild текущего списка дочерних объектов на newChild. Удаление объекта oldChild
selectNodes(patternString) selectSingleNode(patternString) Возвращает объект XMLDOMNodeList, выбранное по шаблону поиска или первый узел
transformNode(stylesheet)
transformNodeToObject(stylesheet, outputObject)
Назначает стилевую таблицу для поддерева текущего узла и возвращает строку - результат обработки. В качестве параметра передается ссылка на объект DOMDocument, в котором находятся XSL инструкции.

Объект XMLDOMNodeList
Представляет собой список узлов - поддеревья и содержит методы, при помощи которых можно организовать процедуру обхода дерева.
length число элементов списка узлов
item(i) Выбор i-того элемента из списка. Возвращает объект XMLDOMNode
nextNode() Выбор следующего элемента в списке.

Использование XML в бизнесе.

Для более ясной картины необходимо пояснение, а зачем все это нужно с тем, что бы понять, как это работает…

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

С одной стороны, приложение выступает в качестве клиента, которое в режиме POST выдает HTTP запрос, с другой стороны, находится WEB сервер, на стороне которого осуществляется обработка запроса и выдача ответа. В качестве обмена используются XML-документы.

Например, в простой корпоративной ERP системе бухгалтерской программе (АСУ Бухучет) необходимо сформировать некий запрос на выписку накладной и передать его в филиал, который имеет склад (АСУ Склад). АРМ Аналогичная постановка задачи при создании В2В системы, когда Предприятие А запрашивает наличие продукции (делает заказ на приобретение) у Поставщика В.

Предприятие А и его программа выступает в качестве клиента. Склад обслуживает Поставщик В, у которого находится складской комплекс БД на SQL сервере. Обмен осуществляется через корпоративный WEB сервер Поставщика В.

Ниже представлен следующий типовой алгоритм обмена:

схема организации обмена с использованием XML технологии
Рис 3.
  1. Предприятие А инициирует процесс А (заказ продукции), который выступает в качестве WEB-клиента.
  2. Процесс А формирует XML документ (например запрос- накладная) и передает его как POST запрос http на WEB сервер Поставщика В. В качестве URI - используется идентификатор ресурса обрабатывающего приложения. URI может быть одинаковым как для всех типов документов, либо индивидуальным для каждого типа. Все зависит от структуры B2B (WEB) сервера.
  3. WEB сервер анализирует запрос и порождает серверный Процесс В, передавая в качестве параметра тело XML документа.
    Процессе В запускается WEB-сервером и обрабатывается либо как ASP страница,CGI (ISAPI) - приложение или JAVA севрлет (серверное приложение)
  4. Процесс В - формирует запрос на SQL-сервер базы данных.
  5. SQL-сервер производит необходимые операции в БД, формирует ответ и возвращает его Процессу В.
  6. По ответу от SQL-сервера Процесс В формирует XML документ (ответ) и возращает его как на ответ на http запрос клиентскому приложению.
  7. Далее, в зависимости от ситуации на стороне клиента формируется либо новый http запрос, либо заканчивается сеанс.

Несколько слов об организации документооборота.

Общим правилом разработки системы обмена XML документами является:

  • во-первых - разработка схемы потоков электронных документов и их структуры;
  • во-вторых - разработка таблиц функций процессов (подпроцессов) т.е. какую функцию по отношению к какому XML-документу будет реализовывать каждый процесс.

Каждый XML документ, подобно HTML документу, должен состоять из заголовка сообщения (информация заключенная тагами

) и тела сообщения (для запроса эта информация обрамленная тагами для ответа на запрос ). Для того, чтобы XML документ был правильно сформирован, необходимо его две составные части "Заголовок" и "Запрос" обрамить тегами, например <xmlDoc>. Вид типового документа представлен ниже:

структура XMLдокумента структура Заголовка XML документа Рис 4. Рис 5.

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

Для запущенного сервером Процесса, алгоритм обработки предпочтительно (но не обязательно) строить следующим образом:

алгоритм анализа XML документа
Рис 6.
Некоторые принципиальные моменты при создании клиентской части

Как уже пояснялось, при создание XML-документа используется его представление в виде DOM модели. Ниже приведен пример части текста Delphi программы создания заголовка xml сообщения.

procedure TThread1.HeaderCreate(Sender: Tobject);
var
  coDoc        : CoDomDocument ;              // объявление сокласса, необходим для создания 
  Doc          : DomDocument ;                // объекта XMLDomDocument
  r            : IXMLDOMElement;              // объявление объектов DOMElement
  Node         : IXMLDOMElement;              //                                  
  txt          : IXMLDOMText;                 //                     DOMText
  attr         : IXMLDOMAttribute;            //                     DOMAttribute
begin

  Doc:=coDoc.Create;                          // создание документа DOM
  Doc.Set_async(false);                       // установка синхронного режима обрабработки
  Doc.LoadXML('<Header/>');                   // начальная инициация DOM документа 
  r:=Doc.Get_documentElement;                 // получение адреса корневого элемента

  Node := Doc.createElement ( 'Sender');        // создание DOMElement (таг <Sender>) 
  txt := Doc.createTextNode( 'ООО "Тайфун"');   // создание техстового узла 'ООО "Тайфун"'
  Node.appendChild(txt);                        //  присвоение узлу <Sender> значение 
                                                // техстового узла 'ООО "Тайфун"'
  r.appendChild(Node);                          // добавление элемента <Sender> в корень
                                                // документа как дочернего
  Node := Doc.createElement ( 'From');          // аналогичные операции для тага <From>
  
  txt := Doc.createTextNode( 'http://tayfun.ru/xml/default.asp');
  Node.appendChild(txt);
  r.appendChild(Node);

  Node := Doc.createElement ( 'To');             // аналогичные операции для тага <To>
  txt := Doc.createTextNode( 'http://irbis.ru');
  Node.appendChild(txt);
  r.appendChild(Node);
  
  Node := Doc.createElement ( 'TypeDocument');           // создание DOMElement (<TypeDocument Id>) 
  Att := Doc.createAttribute ( 'Id ', ' Order');         // создание узла XMLDOMAttribute
  Node.appendChild(Att);                                 //    <TypeDocument Id="Order"/>
  r.appendChild(Node);

end;

Следует отметить, что объявление переменной coDoc : CoDomDocument и Doc : DomDocument , а также ее создание методом Create ( Doc:=coDoc.Create;) осуществляется один раз. Объявление переменной находится в секции описания глобальных переменных, а не в локальной процедуре, как было продемонстрировано для наглядности в данном примере (т.е. одна глобальная переменная типа DomDocument на один программный модуль).

Результатом работы вышеприведенной программы будет созданный заголовок <Header>, приминительно к нашему примеру xml-документа: изображен на рис. 7.

структура заголовка XMLдокумента структура таблиц БД
Рис 7. Рис 8.

Основное приемущество передачи информации в виде XML-документов в том, что существует возможно формировать сообщение, используя независимые структуры таблиц в СУБД как на принимаемой, так и на передаваемой стороне. Используя наш пример, пусть требуется передать информацию об инвойсах Предприятия А, из СУБД имеющий структуру, изображенную на рис. 6

Для формирования xml-документа, содержащего инвойс первоначально строится SQL-запрос (запрос А) с информацией о самом инвойсе:

    SELECT * FROM Invoice_General
    WHERE InvoiceNum = :num                      // :num  - параметр, который задает номер инвойса. 

и далее строится SQL-запрос (запрос В) информация о товарах, описываемых в инвойсе (детальная спецификация):

    SELECT Goods,Qulity,Price, HZ_cod 
    FROM Goods 
    WHERE InvoiceNum = :num                      // :num - параметр, который задает номер инвойса. 

Ниже представлена часть программы, формирующей тело xml-документа:

procedure TThread1.DataBodyCreate(Sender: Tobject);
var
  //coDoc      : CoDomDocument ;              // объявление сокласса и объекта XMLDomDocument 
  //Doc        : DomDocument ;                // должно быть глобальным, для всего модуля. 
  
  r            : IXMLDOMElement;              // объявление объектов DOMElement
  Node, Node2  : IXMLDOMElement;              //                     DOMElement;
  Node3, Node4 : IXMLDOMElement;              //                                  
  txt          : IXMLDOMText;                 //                     DOMText
  str          : String;

// InvoiceNumber: integer;  - глобальная переменная - имеет значение 987654 
// queryA, queryB : String;  - глобальная переменная, имеет значение, соответсвующее запросу
// queryA - запрос А генеральная информацией об инвойсе
// queryB - запрос B информация о товарах, описываемых в  инвойсе (см. текст)

begin

  Query.Close;                                     // закрывает запрос для доступа
  Query.Text := queryA;                            // см. по тексту "запрос А"

 Query.Params[0].AsInteger := InvoiceNumber;       // присваивание значения параметров
 Query.ExecSQL;                                    // выполнение запроса
 Query.Open;                                       // открытие доступа к данным запроса 

  r:=Doc.Get_documentElement;                      // получение адреса корневого элемента

  Node2 := Doc.createElement ( ' Request ');       // создание DOMElement (таг <Request>) 
  Node := Doc.createElement ( 'Invoice');          // создание DOMElement (таг <Invoice >) 
  r.appendChild(Node2);                            // добавление элемента <Request> в корень
  Node2. appendChild(Node);                        // добавление элемента <Invoice> в <Request> 
  
  Node3 := Doc.createElement ( 'Depurture') ;      // создание DOMElement (таг <Depurture>)  
  Node. appendChild(Node3);                        // добавление элемента <Depurture> в <Invoice>

  str:= Query.FieldByName('Depurture').AsString;   // обращение к полю 'Depurture' запроса
  txt := Doc.createTextNode( str);                 // создание техстового узла = значению поля  
  Node.appendChild(txt);                           //  присвоение узлу <Invoice> значение 
                                                   // техстового узла, переменной str 

// аналогичные операции для тага <Destination>, <DataSend>, <DataDepurture>, <Currency>
// <DestinationCompany> (поле DB  "Consignee" )

  Node := Doc.createElement ( 'Destination');                  
  str:= Query.FieldByName('Consignee ').AsString;    // имя поля БД может и не совпадать с именем 
  txt := Doc.createTextNode( str);                   // тага, в этом приемущество использования 
  Node.appendChild(txt);                             // DOM интерфейса перед СУБД, имеющим 
                                                     // поддержку XML-интерфейса, типа ORACLE 8i 
...                                                  // или Ms SQL 2000
                                                     // формирование запроса на спецификацию по товарам 
 Query.Close;                                        // закрывает запрос для доступа
 Query.Text := queryВ;                               // см. по тексту "запрос В", информац. О товарах

 Query.Params[0].AsInteger := InvoiceNumber;         // присваивание значения параметров
 Query2.ExecSQL;                                     // выполнение запроса
 Query.Open;                                         // открытие доступа к данным запроса 

Node3 := Doc.createElement ( ' Imems') ;             // создание DOMElement (таг <Imems>)            
Node. appendChild(Node3);                            // добавление элемента <Imems> в <Invoice>

while not Eof.Query do begin                         // цикл по всем строкам запроса
   Node4 := Doc.createElement ( 'Imem');
   Node3.appendChild(Node4);                         // добавление элемента <Imem> в <Imems>
  
  str:= Query.FieldByName('Price').AsString;         // формирование данных для тага <Price>
  txt := Doc.createTextNode( str); 
  Node.appendChild(txt); 
  ...
// аналогичные операции для тагов <HZ_Cod>, <Quality>, <GoodName>
  end;
end;

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

текст XML документа

Для формирования запроса используется метод Open объекта IXMLHttpRequest:

procedure Open(const bstrMethod, -тип метода = "POST"
  bstrUrl, -Url адрес сервера
  varAsync, -режим связи асинхронный / синхронный = true
  bstrUser, -имя пользователя для аутентификации
  bstrPassword) - пароль
Создании серверной части обработки документа

Как было отмечено ранее, обработка HTTP запроса может осуществляться либо CGI-приложениями, либо Java-сервлетами. Возможен и вариант написания ASP-страниц. Но в этом случае передача данных возможна только методом "GET" через строку запроса. Хотя, обработка HTTP запроса ASP-страниц работает более эффективнее, чем CGI-приложением. Однако, на мой взгляд, без разницы, как обрабатывать, а важнее решить вопрос - как построить программму обработки, а не какими средствами.

Если из предыдущей главы мы рассмотрели варианты формирования XML-документ, то задача серверного приложения обратная - разбор XML-документов. Ниже представлена часть программы, осуществляющей разбор xml-документа:

procedure Tthread1.DataParser(Sender: Tobject);
var

  r,FNode          : IXMLDOMElement;                       // объявление объектов DOMElement
  Str,Filename     : String;
  parm             : String;

CoDocXML, CoDocXSL, CoDocResult      : CoDomDocument ;     // объявление сокласса и
XMLDoc, XSLDoc, ResultDoc            : DomDocument ;       // объекта XMLDomDocument 

// HttpStr : String; - глобальная переменная, содержащая строку HTTP запроса

Begin

  XMLDoc:=coDocXML.Create;                 // создание документа XMLDoc
  XMLDoc.Set_async(false);                 // установка синхронного режима обрабработки
  XMLDoc.LoadXML(HttpStr);                 // загрузка DOM документа из строки HttpStr

  r:=Doc.Get_documentElement;                        // получение адреса корневого элемента
  FNode:= r.SelectSingleNode("//TypeDocument");      // получение значения элемента <TypeDocument>
  FileName:= FNode.GetAttibute("id");                // получение значения аттрибута id="Order"
  FileName:= FileName+".xsl";                        // и формирование имени файла Order.xsl

  XSLDoc:=coDocXSL.Create;                           // создание документа XSLDoc
  XSLDoc.Set_async(false);                           // установка синхронного режима обрабработки
  XSLDoc.LoadXML(FileName);                          // загрузка DOM документа из файла Order.xsl

  ResultDoc:=coDocResult.Create;                     // создание документа XMLDoc
  ResultDoc.Set_async(false);                        // установка синхронного режима обрабработки
  ResultDoc.validateOnParse := true;                 // установка проверки разбора
 
  XMLDoc.transformNodeToObject(XSLDoc, ResultDoc);   // разбор XMLDoc по XSL-шаблону
	 
 Str:= ResultDoc.text;                               // переменной Str присваивается текстовое значение 
                                                     // результирующего документа.

 FNode:= r.SelectSingleNode("//InvoiceNumber");      // поиск элемента <InvoiceNumber>
 parm:= FNode.text;                                  //  и получение значения элемента

 Query.Close;                                        // закрывает запрос для доступа
 Query.Text := Str; 
 Query.Params[0].AsString := parm;                   // присваивание значения параметра
 Query.ExecSQL;                                      // выполнение запроса

end;

Вся изюминка разбора заключается в применении XSL-шаблона, который сформирован для каждого типа документа индивидуально. Результатом разбора является строка SQL-запроса. Впоследствие выполнение сформированной строки SQL-запроса осуществит необходимые изменения данных в СУБД.

Приимущество использования разбора через щаблон еще и в том, что получается некая гибкость данных, и получается полная независимость работы алгоритма от программного кода. Ниже приведен используемый для обработки документа типа ORDER текст XSL-шаблона:

<!-- файл Order.xsl  -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">

  <xsl:template match="/">
  <!--  применяем шаблон ко всему документу, начиная с корневого элемента "/"        -->

  <HTML>
  <xsl:for-each select="//header">

     <!-- формирование запроса для записи данных                          -->
     <!-- в таблицу регистрации приходящих сообщений TABREG       -->
     INSERT into TABREG ( FROM, TO, TYPEDOC,body) VALUES( ' 
      <xsl:value-of select="from" />' ,' 
      <xsl:value-of select="to" />','<xsl:value-of select="TypeDocument/@id" />' ) 
  </xsl:for-each>

<!-- формирование запроса для записи данных в таблицу GOODS -->
<!--  информация о товарах -->
   <xsl:for-each select="//item">
      INSERT into GOODS ( invoiceNumber, name, price, quality) VALUES( ' :num',
     '<xsl:value-of select="name" />' , '<xsl:value-of select="price" />', 
     '<xsl:value-of select="quality" /> 
  ' ) 
  </xsl:for-each>

  </HTML>
  </xsl:template>
</xsl:stylesheet>

Поясняя вышеприведенный пример, надо отметить, что использование пары тагов <HTML> и </HTML> носит формальный характер, т.к. после разбора в результирующем XML-документе формально должен присутствовать хотябы один узел. Метод ResultDoc.text присваивает текстовае значение полученного в ходе разбора XML-документа ResultDoc. В этом случае значением является все то, что обрамлено пары тегов <HTML> и </HTML>, т.е. сформированный нами SQL-запрос.

Другой особенностью написания программы надо отметить возможность использования SQL-параметра :num. Использование параметра позволяет упростить текст xsl-шаблона. Определение значение соответствующих элементов узлов XML-документа определякется первоночально выбора по имени соответствующего узла, например:

FNode := r.SelectSingleNode("
  //InvoiceNumber");   // поиск элемента >InvoiceNumber&gt; и далее использование свойства text:
  parm := FNode.text; //  и получение значения элемента &gt;InvoiceNumber&gt;
Коротко об XSL

Абревиатура XSL происходит от eXtensible Stylesheet Language - язык форматирования таблиц стилей (XML данных). Как понятно из заголовка eXtensible Stylesheet Language (XSL) используется для форматирования XML данных. По определению W3C XSL состоит из двух частей:

  • XSLT - XSL Transformation. Язык, используемый для преобразования или форматирования (трансформирования) XML документов. Таким образом, при помощи XSLT мы можем получить разные разрезы множества данных и формы представления данных.
  • Элементы форматирования. К этим элементам относятся все элементы типографического оформления данных, после их обработки их при помощи XSL. Используется только для формирования HTML страниц.

При помощи XSLT мы можем отобрать нужные нам данные из XML файла, и оформить их в виде для предоставления пользователю. Например, в нашем случае мы преобразовали XML данные в виде SQL запроса. Классическое применение XSL - это, как правило форматирование данных в виде HTML страниц или более редкое представление в виде RTF файлов.

XSL файл описывает шаблон (template), согласно которому будет совершаться преобразование XML данных. Возращаясь к xsl-шаблонам, в XSLT можно выделить следующие элементы (директивы):

XSL-директивы описание
xsl:apply-templates Директива, указывающая на применение соответствующих шаблонов аттрибуту select="имя шаблона"
xsl:attribute создает дерево аттрибутов и добавляет его в выходной элемент, пареметр name="имя аттрибута", namespace - URI на пространство имен (преффикс пространства имен)
xsl:call-template вызывает шаблон, аттрибуту name=" URI на шаблон"
xsl:choose
xsl:when
xsl:otherwise
осуществление выбора по условию xsl:when expr="вычисление выражения на script ",
language="language-name"
test= "вычисляемое выражение"
xsl:comment генерирует комментарий в выходной документ
xsl:copy
xsl:copy-of
копирует текущей узел в выходной источник или вставляет фрагмент документа в узел, где аттрибут select="имя узла источника"
xsl:element создает выходной элемент по имени, аттрибут name="имя элемента", namespace="uri сслылка на пространство имен"
xsl:for-each повторно применяет шаблон ко всем узлам списка узлов, аттрибут select задает список узлов
xsl:if проверка условия, задается аттрибутом test в виде выражения
xsl:include включает внешний шаблон, аттрибут href = "URI reference"
xsl:output специфицирует выходной результат, аттрибут method может иметь значения "xml", "html" или "text"
xsl:param специфицирует значение параметров, аттрибут name="имя параметра", select = "значание"
xsl:processing-instruction создает инструкцию обработки, аттрибут name="имя процесс инструкции"
xsl:sort сортирует множество узлов, аттрибуты select = "имя узла", data-type = тип данных {"text" | "number" | Qname}, order = направление сортировки {"ascending" | "descending"}
xsl:stylesheet определяет документ xsl-шаблонов, является корневым элементом для XSLT
xsl:template определяет xsl-шаблон, аттрибут name= " URI преффикс на имя шиблона", match= "указание на узел, к которому применяется шаблон"
xsl:text генерирует текст в выходной поток, аттрибут disable-output-escaping = "yes" или "no", указывает на возможность генерации символов ESC
xsl:value-of вставляет значение выбранного узла как текст, аттрибут select= "указатель на узел" из которого берут значение
xsl:variable специфицирует значение границ переменных, аттрибут name = "имя переменной", select = "вычисление значения переменной"
xsl:with-param применяет параметр к шаблону, аттрибут name ="имя параметра", select = выражение для вычисления текущего контекста, значениие по умолчанию "."

Заключение

В заключение, необходимо отметить, что использование стандартного XML-парсера msxml.dll является не единственным средством разбора и создания XML-документов. Например, для создание XML документов эффективно использовать компоненты TPageProduser и TТableProduser. Но, данная статья лишь подчеркивает широту и возможность применения на практике DOM модели .

Автор будет очень благодарен за отзывы об актуальности темы, общем содержании, стиле изложения, а также всем остальным комментариям, которые помогут в дальнейшем улучшить качество написания сборника статей и выпуску книги, освещающую тему практической стороны использования XML-документов в электронной коммерции. Более подробную информацию о практической стороне применения электронных документов можно почерпнуть на авторском сайте www.eDocs.al.ru Также на авторском сайте планируется разместить исходные тексты и примеры.






Copyright © 2004-2016 "Delphi Sources". Delphi World FAQ




Группа ВКонтакте   Ссылка на Twitter   Группа на Facebook