БД и XML Ижевский Виталий Григорьевич Спецвыпуск: Хакер, номер #052, стр. 052-066-3 Разработка UDF Разрабатывать UDF будем с помощью старого доброго Delphi (кто любит С, можно и на C). Для начала создадим файл с описаниями нужных COM-интерфейсов. Project Import type library, выбираешь нужную библиотеку, жмешь Create Unit. Delphi создаст файл msxml2_tlb.pas. Этот файл прописываешь в uses-секции модуля свежесозданной библиотеки UDF. А теперь открою секрет: компания Borland в документации оговаривает, что компилятор Delphi автоматически подключит код инициализации COM. Вранье, нужно все делать самому :). Для этого пропиши нужные процедуры: unit Unit1; interface uses msxml2_tlb, ActiveX; implementation initialization CoInitialize(nil); IsMultiThread:=true; loadXML; finalization FreeXML; CoUnInitialize; end. Еще один секрет: CoInitialize(nil) нужно прописывать обязательно перед IsMultiThread:=true (кто раньше писал UDF, тот знает, что параметр IsMultiThread нужен для работы с многопользовательской БД). Как все работает? Коротко принцип решения. При первой загрузке UDF (когда будет первый запрос SQL c ее использованием, а не тогда, когда запустится сервер или появится коннект к БД, которая использует UDF) выполнится процедура loadXML, которая загрузит XML-файл в память. UDF будет висеть в памяти (вместе с твоими данными), пока есть коннекты к этой БД (независимо от транзакций и прочих вещей). А когда коннекты закроют, UDF выгрузится, выполнится FreeXML и уничтожатся COM-объекты. А как же получить доступ к нужным элементам документа XML? Для этого существует механизм DOM. С помощью DOM XML парсер показывает пользователю документ как некую программную иерархию узлов и предоставляет программисту набор методов и функций, с помощью которых можно манипулировать этими узлами. Через созданный в Delphi файл описания COM-интерфейсов msxml2_tlb.pas ты можешь получить доступ к DOM XML. Ниже пример использования DOM для загрузки и выгрузки XML-документа в UDF: uses msxml2_tlb, ActiveX; … var xmldCom :CoDOMDocument; xmld :IXMLDOMDocument2; … procedure LoadFirstXML(const fileName:string); begin xmld:=CoDOMDocument.Create; xmld.async:=false; xmld.load(fileName); xmld.setProperty('SelectionLanguage','XPath'); if xmld.parseError.errorCode<>0 then begin exit; end; procedure freeXML; begin xmld:=nil; end; Для доступа к конкретным элементам документа можно использовать функцию selectSingleNode или SelectNodes: xmld.documentElement.selectNodes(xPath) |