Назад в библиотеку

Використання XML в середовищі Delphi (вихідні коди)

Автор:І.І. Вадим
Источник: ЕASYСODE - Програмування, легко про складне - 2012

Анотація

Вадим І.І. Використання XML в середовищі Delphi (вихідні коди). У статті розглянуто використання XML в серд Delphi (основні вихідні коди). Автором проаналізовано шаблон XML-файлів - XLS-шаблон.

Використання С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

У файлі 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 сервер Постачальника В.

Нижче представлений наступний типовий алгоритм обміну.

Типовий алгоритм обміну

Рисунок 1 - Типовий алгоритм обміну

  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 документ, подібно HTML документу, повинен складатися із заголовка повідомлення (інформація укладена тагамі) і тіла повідомлення (для запиту ця інформація обрамлена тагамі для відповіді на запит ). Для того, щоб 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"); / / отримання значення елемента 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"); / / пошук елемента parm: = FNode.text; / / і отримання значення елемента

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

end;

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

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

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

<xsl:template match=”/”>

<xsl:for-each select=”//header”>

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>

<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>

xsl:template> xsl:stylesheet>

Пояснюючи вищенаведений приклад, треба зазначити, що використання пари тегів і носить формальний характер, тому що після розбору в результуючому XML-документі формально повинен бути присутнім хоча б один вузол. Метод ResultDoc.text присвоює текстовае значення отриманого в ході розбору XML-документа ResultDoc. У цьому випадку значенням є все те, що обрамлене пари тегів і, тобто сформований нами SQL-запит.

Іншою особливістю написання програми треба відзначити можливість використання SQL-параметра :num. Використання параметра дозволяє спростити текст xsl-шаблону. Визначення значення відповідних елементів вузлів XML-документа определякется первоночально вибору на ім'я відповідного вузла, наприклад:

 FNode: = r.SelectSingleNode ("/ / InvoiceNumber"); / / пошук елемента> InvoiceNumber> і далі використання властивості text: 

 parm: = FNode.text; / / і отримання значення елемента> InvoiceNumber> 

Коротко про XSL

Абревіатура XSL походить від eXtensible Stylesheet Language – мова форматування таблиць стилів (XML даних). Як зрозуміло з заголовка eXtensible Stylesheet Language (XSL) використовується для форматування XML даних. За визначенням W3C XSL складається з двох частин:

За допомогою 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 моделі.