Форум » [x]Harbour » XML как таблица » Ответить

XML как таблица

Vlad04: XML вытесняет DBF, складывается впечатление, по всем фронтам. Про отчеты в гос. органы я молчу, там это уже давно. Теперь вот стали справочники поставлять в виде XML, раньше были в виде DBF. Возникает необходимость подключение XML , как таблицы.Не разбор и чтение, а именно подключение. Можно, конечно, конверторы придумать, но это уже не та оперативность Кстати, в Делфи такая возможность существовала давно. Насколько я понимаю, в Харбор возможности подключить XML в виде таблицы нет? Т.е. соответствующих RDD нет.

Ответов - 19

azoo: Мне кажется сравнивать DBF и XML не стоит. DBF-таблица, XML-больше на граф похожа.

Vlad04: Речь идет не о сравнении, а о работе с данным формой предоставления информации. XML прекрасно встраивается в ЗАПРОСЫ, уже не является плоской таблицей и т.д. и т.п.

alkresin: Что вы подразумеваете, когда говорите о "подключении" ? Что вы хотите сделать с XML-файлом, "подключив" его ?


PSP: alkresin пишет: Что вы подразумеваете, когда говорите о "подключении" ? Видимо, он хочет иметь возможность открывать xml, как обычный dbf, к примеру, командой use. Чтобы некая прослойка-RDD осуществляла парсинг и управляла чтением-записью в этом xml. Наверное, это подразумевается.

alkresin: Набор методов RDD ориентирован на работу с плоской таблицей, а XML - сложная иерархическая структура, поэтому не может быть RDD для работы с произвольным XML. Первоначальный вопрос был: Насколько я понимаю, в Харбор возможности подключить XML в виде таблицы нет? В общем случае нельзя подключить в виде таблицы то, что таблицей не является, хотя, конечно, какие-то конкретные XML-документы могут иметь табличное представление. В принципе, можно написать класс и в методе Init установить, что, скажем, тэг <xxx> определяет строки, а <yyy> - колонки. Можно реализовать методы для перемещения по "строкам", чтения/записи "полей". Но это не будет универсальным средством для работы с XML, это будет средством для работы с XML определенной, очень простой, структуры.

Vlad04: alkresin, PSP Видимо, он хочет иметь возможность открывать xml, как обычный dbf, Об этом речь и идет. Конечно, не всякий XML так можно подключить, но простые, которыми по сути являются справочники - подключаются. Как я уже писал, в Делфи есть пример подобного подключения. Сейчас ищу, где-то видел. Ну а "хотелки" появились не на ровном месте, просто справочники, которые получали централизованно раньше были в формате DBF,с нового года стали вот такими XML - поменяли формат.

alkresin: Самый простой вариант - конвертнуть эти справочники в dbf. И поиск по справочнику будет потом гораздо быстрее (если проиндексировать), чем по XML - файлы-то, наверняка, не маленькие.

Vlad04: Самый простой вариант - конвертнуть эти справочники в dbf. Из ДБФ в XML - просто ,при чем любую базу , а обратно что-то не нашел универсального метода. Единственно - разбор XML и т.д

PSP: Vlad04 пишет: Единственно - разбор XML и т.д А другого способа и нет. Парсить придется в либом случае)

alkresin: Vlad04 пишет: Из ДБФ в XML - просто ,при чем любую базу , а обратно что-то не нашел универсального метода. Универсального и быть не может. Можно написать функцию или класс, которые это сделают для некоторых XML, если на входе указать особенности структуры - имя тэга "строки", имя тэга "столбца", имена родительских тэгов ( "столбцы" же могут быть вложены не непосредственно в "строки" ).

ММК: Vlad04 пишет: Об этом речь и идет. Конечно, не всякий XML так можно подключить, но простые, которыми по сути являются справочники - подключаются. Как я уже писал, в Делфи есть пример подобного подключения. Сейчас ищу, Вот примерчик на FWH . Здесь XML вешается на "дерево" #include "FiveWin.ch" #include "Splitter.ch" static oSplit1, oSplit2, oLbxDatas, oLbxMethods //----------------------------------------------------------------------------/ function Test() local oWnd DEFINE WINDOW oWnd TITLE "XML viewer" ; MENU BuildMenu() ACTIVATE WINDOW oWnd ; ON INIT BuildTree( oWnd ) ; ON RESIZE ( If( oSplit1 != nil, oSplit1:AdjLeft(),),; If( oSplit2 != nil, oSplit2:AdjRight(),) ) return nil //----------------------------------------------------------------------------/ function BuildMenu() local oMenu MENU oMenu MENUITEM "About" ACTION MsgAbout( "XML Viewer", "(c) FiveTech Software 2013" ) ENDMENU return oMenu //----------------------------------------------------------------------------/ function BuildTree( oWnd ) local oTree := TTreeView():New( 0, 0, oWnd ) local oClass, cData, cMethod local hFile, oXmlDoc, oXmlIter, oTagActual local oTagLast, aRoots := {} oTree:nWidth = 180 // oTree:SetImageList( oImageList ) oTree:Expand() @ 0, 186 LISTBOX oLbxDatas VAR cData ITEMS {} ; SIZE 200, 200 PIXEL OF oWnd @ 0, 391 LISTBOX oLbxMethods VAR cMethod ITEMS {} ; SIZE 200, 200 PIXEL OF oWnd @ 0, 181 SPLITTER oSplit1 ; VERTICAL ; PREVIOUS CONTROLS oTree ; HINDS CONTROLS oLbxDatas ; LEFT MARGIN 150 ; RIGHT MARGIN oSplit2:nLast + 100 ; SIZE 4, 300 PIXEL ; OF oWnd STYLE @ 0, 386 SPLITTER oSplit2 ; VERTICAL ; PREVIOUS CONTROLS oLbxDatas ; HINDS CONTROLS oLbxMethods ; LEFT MARGIN oSplit1:nFirst + 120 ; RIGHT MARGIN 80 ; SIZE 4, 300 PIXEL ; OF oWnd STYLE hFile = FOpen( "test.xml" ) oXmlDoc = TXmlDocument():New( hFile ) oXmlIter = TXmlIterator():New( oXmlDoc:oRoot ) AAdd( aRoots, oTree ) while ( oTagActual := oXmlIter:Next() ) != nil if oTagLast != nil if oTagLast:Depth() < oTagActual:Depth() ASize( aRoots, Len( aRoots ) + 1 ) aRoots[ oTagActual:Depth() + 1 ] = aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName ) aRoots[ oTagActual:Depth() + 1 ]:Cargo = oTagActual endif if oTagLast:Depth() > oTagActual:Depth() aRoots[ oTagActual:depth() + 1 ] = aRoots[ oTagActual:Depth() ]:Add( oTagActual:cName ) aRoots[ oTagActual:depth() + 1 ]:Cargo = oTagActual endif if oTagLast:Depth() == oTagActual:Depth() aRoots[ Max( oTagLast:Depth(), 1 ) ]:Add( oTagActual:cName ):Cargo = oTagActual endif else AAdd( aRoots, oTree:Add( oTagActual:cName ) ) ATail( aRoots ):Cargo = oTagActual endif oTagLast = oTagActual end FClose( hFile ) oTree:bChanged = { | oItem | oLbxDatas:SetItems( { oItem:GetSelected():Cargo:cData } ),; oLbxMethods:Reset(),; HEval( oItem:GetSelected():Cargo:aAttributes,; { | cKey, cData | oLbxMethods:Add( cKey + " : " + cData ) } ) } return nil Или вот здесь обсуждение посмотрите, может наведет на мысль ... http://forums.fivetechsupport.com/viewtopic.php?f=3&t=33506&sid=2613387c1e321200444f700cf80b6690

Vlad04: Да, открывает xml

Vlad04: В MiniGui какую библиотеку надо подключить для сборки проекта, в котором есть TXmlDocument() ?

Vlad04: #include "SIMPLEIO.CH" # include "hbXml.ch" # include "Fileio.ch" PROCEDURE Main (nnmm) LOCAL oXmlDoc := TXmlDocument():new() LOCAL oXmlNode,sSTR:='' //, aStruct := {} # define crlf chr(13) PRIVATE nHandle oXMlDoc:read( Memoread( nnmm ) ) oXmlNode := oXmlDoc:findFirst() nHandle = fCreate ("oUT.txt", 0) DO WHILE oXmlNode <> NIL sStr:= oXmlNode:cName+" = "+HB_ANSITOOEM(XtOC(oXmlNode:cData)) //+" | " fWrite( nHandle,sSTR+ crlf ) oXmlNode := oXmlDoc:findNext() ENDDO FCLOSE (nHandle) RETURN Простой разбор XML, результат в - текст. Запись в БД, если известна ее структура проблем то же нет

Vlad04: Пример на Делфи подключения XML Поведение , как у обычной таблицы. Правда , структура XML должна быть предварительно описана.

Dima: Vlad04 пишет: Поведение , как у обычной таблицы Похоже грузится в массив а далее идет бровс по массиву.

Vlad04: Похоже грузится в массив а далее идет бровс по массиву. Нет. Источник данных и к нему подключение. В модуле добавляется описание структуры. При изменении данный в полях и добавлении все сразу же и сохраняется. Это, наверно, определенная универсальность Делфи

Vlad04: Вот на этом остановился #include "SIMPLEIO.CH" # include "hbXml.ch" # include "Fileio.ch" PROCEDURE Main (sName) LOCAL oXmlDoc := TXmlDocument():new() LOCAL oXmlNode,sNameNod:='', sNameXML:='',sNameDbf:='' LOCAL mFild:={},i # define crlf chr(13) REQUEST DBFCDX , DBFFPT REQUEST HB_CODEPAGE_RU866 hb_SetCodepage("RU866") set date brit set century on if (i:=AT('.',sName)) >0 sName:=Left(sName,i-1) endif sNameXML:=sName+'.xml' sNameDbf:=sName+'.DBF' if !File(sNameDbf) ?' НЕт DBF ' Quit endif if !File(sNameXML) ?' НЕт XML ' Quit endif Select 0 Use (sNameDbf) Via "DBFCDX" alias Basa zap mFild:=ARRAY(FCOUNT()) AFIELDS(mFild) oXMlDoc:read( Memoread( sNameXML ) ) oXmlNode := oXmlDoc:findFirst() DO WHILE oXmlNode <> NIL sNameNod :=Alltrim(oXmlNode:cName ) if sNameNod == 'zap' Append Blank else if AsCan(mFild,sNameNod) >0 if ValType(&(sNameNod)) ='D' Repl &(sNameNod) with Ctod(HB_ANSITOOEM(XtOC(oXmlNode:cData))) elseif ValType(Basa->&(sNameNod)) ='C' Repl &(sNameNod) with (HB_ANSITOOEM(XtOC(oXmlNode:cData))) elseif ValType(Basa->&(sNameNod)) ='N' Repl &(sNameNod) with Val(HB_ANSITOOEM(XtOC(oXmlNode:cData))) endif endif endif oXmlNode := oXmlDoc:findNext() ENDDO RETURN Особенности : - таблица и XML имеют одинаковое наименование ( без расширения) - новая запись в XML начинается с тэга <ZAP>

PSP: А без парсинга всё равно никак)))



полная версия страницы