Seite 1 von 1
XML Dateien einlesen
Verfasst: Mi, 17. Aug 2022 13:20
von Manfred
Hi,
Ich möchte eine XML Datei einlesen und die Daten weiterverarbeiten. Wie geht man da vor? Ich öffne die Datei mit XMLDocOpenFile(). Und wie geht es dann weiter? Gibt es eine bestimmte Reihenfolge, die man einhalten muß, oder wie kommt man an die einzelnen Inhalte der Datei?
Re: XML Dateien einlesen
Verfasst: Mi, 17. Aug 2022 13:36
von Tom
Schau Dir mal "
XmlSimpleParser()" an (findest Du in den Docs).
Ich arbeite in diesem Bereich nur noch mit Chilkat, das ist sensationell - und es liefert Dir z.B. auf Basis einer bestehenden XML-Datei den Code zur Bearbeitung, etwa für FoxPro. Den kann man leicht nach Xbase++ adaptieren:
http://tools.chilkat.io/xmlParse
Re: XML Dateien einlesen
Verfasst: Mi, 17. Aug 2022 14:26
von Manfred
jetzt stellt sich mir die nächste Frage, kann man damit überhaupt Dateien einlesen, die größer als 2GB sind? ich bekomme immer nur "0" zurück
Re: XML Dateien einlesen
Verfasst: Do, 18. Aug 2022 17:59
von Manfred
die Datei ist zu groß für xbase++, wie ich mir habe sagen lassen.
Re: XML Dateien einlesen
Verfasst: Do, 18. Aug 2022 18:08
von AUGE_OHR
hi
Manfred hat geschrieben: ↑Do, 18. Aug 2022 17:59
die Datei ist zu groß für xbase++, wie ich mir habe sagen lassen.
grundsätzlich kann eine 32 Bit App auch Dateien > 2 GB "verarbeiten", aber du brauchst neue Function zum "navigieren"
hier ein Beispiel wie man eine Datei > 2 GB "öffnen" kann, need Ot4xb
Code: Alles auswählen
#include "Fileio.ch"
#include "ot4xb.ch"
PROCEDURE Main(cFile)
LOCAL nPos
LOCAL nHandle
IF FILE(cFile)
nHandle := FOpen(cFile, FO_READWRITE+FO_DENYWRITE)
IF FError() <> 0
? "Fehler beim Öffnen der Datei:", FError()
ELSE
? nPos := FSeek( nHandle, 0 , FS_END )
FSeek( nHandle, 0 , FS_SET )
? nPos := ( ULongLong2Double( STR( FSeek( nHandle, 0 , FS_END ) ) ) )
FSeek( nHandle, 0 , FS_SET )
FClose( nHandle )
ENDIF
WAIT
ELSE
ALERT("need big file")
ENDIF
RETURN
Ot4xb hat entsprechende Function für Pointer > 2 GB
Re: XML Dateien einlesen
Verfasst: Do, 18. Aug 2022 18:10
von Manfred
wie ich schon oben geschrieben hatte, ich wollte die XML... Funktion von xbase++ benutzen. (die kann das aber nicht) Mit Fopen() war ich als erstes dran, das hat mir aber nicht gefallen.
Ich habe jetzt aber erstmal eine andere idee, ich zerlege die Datei in Blöcke. Speicher die jeweils ab und lese die dann einzeln ein. Dann dauert es eben etwas länger. Mal sehen, was mir in der mittleren Zukunft dazu noch einfällt.
Re: XML Dateien einlesen
Verfasst: Do, 18. Aug 2022 18:39
von Tom
XML-Daten sind strukturiert. Das fängt mit der äußeren <XML></XML>-Klammer an und setzt sich dann ebenenweise fort. Es hat deshalb keinen Sinn, XML-Dateien blockweise zu verarbeiten.
Re: XML Dateien einlesen
Verfasst: Do, 18. Aug 2022 18:46
von Manfred
ich meinte ja die Ebenen. Aber so wie ich es gerade sehe, sind selbst die Ebenen noch zu groß
Re: XML Dateien einlesen
Verfasst: Fr, 19. Aug 2022 8:23
von ramses
Schau doch mal bei ot4xb vorbei. Da gibt es einen Wrapper und ein Sample das auf den xml Funktionen von Windows aufbaut.
Re: XML Dateien einlesen
Verfasst: Fr, 19. Aug 2022 9:22
von Tom
Und noch einmal: Chilkat. Die XML-Funktionen darin sind auch kostenlos.
Re: XML Dateien einlesen
Verfasst: Fr, 19. Aug 2022 9:33
von Manfred
@Tom,
ich habe es ja verstanden.
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 0:16
von azzo
Hallo Manfred,
wir haben vor längerer Zeit einen xmlviewer mit Fivewin gemacht.
Mich würde interessieren, ob es auch bei einer großen Datei funktioniert.
LG
Otto
Hier ist der source code:
EXE und prg Download-Link:
https://mybergland.com/fwforum/xmlviewer.zip
Code: Alles auswählen
#include "fivewin.ch"
#include "xbrowse.ch"
#include "hbcompat.ch"
//----------------------------------------------------------------------------//
function XmlView( cXml )
local oXmlDoc, oTree
if ValType( cXml ) != 'C'
cXml := nil
endif
if Empty( cXml ) .and. ;
Empty( cXml := cGetFile( "XML File(*.xml)|*.xml|", "Select GuestRooms XML file",,CurDir() ) )
return nil
endif
BrowseXML( cXml )
return nil
static function BrowseXML( cXml )
local oWnd, oFont, oBrw, oHash
local oTree
msgRun( "Reading " + cFileNoPath( cXml ), "PLEASE WAIT", { || oTree := XmlTree( cXml ) } )
DEFINE FONT oFont NAME "TAHOMA" SIZE 0,-16
DEFINE WINDOW oWnd TITLE cXml
oWnd:SetFont( oFont )
@ 0,0 XBROWSE oBrw OF oWnd SIZE 700,0 PIXEL ;
DATASOURCE oTree COLSIZES 300 NOBORDER CELL LINES
ADD TO oBrw DATA oBrw:oTreeItem:Cargo:Depth() PICTURE "99" HEADER "Dp"
ADD TO oBrw DATA If( Empty( oBrw:oTreeItem:Cargo:aAttributes ), nil, .t. ) HEADER "Atr"
ADD TO oBrw DATA oBrw:oTreeItem:Cargo:cData HEADER "DATA" SIZE 200
WITH OBJECT oBrw
:nHeadStrAligns := AL_CENTER
:nStretchCol := :Data:nCreationOrder
:nHeadStrAligns := AL_CENTER
/*
:bRClicked := { || msginfo( obrw:otreeitem:cargo:path() ), ;
xbrowse( obrw:otreeitem:cargo, obrw:otreeitem:cargo:path() ) }
*/
:bPopUp := { || RClickMenu( oBrw:oTreeItem:Cargo ) }
:aCols[ 1 ]:bLDClickData := { || oBrw:oTree:Expand( oBrw:oTreeItem:nLevel + ;
If( oBrw:oTreeItem:lOpened, 0, 1 ) ), oBrw:Refresh() }
:Atr:SetCheck()
WITH OBJECT :Data
:cDataType := 'M'
:bLDClickData := { |r,c,f,o| o:RunBtnAction }
END
:bChange := { || oHash:aArrayData := oBrw:oTreeItem:Cargo:aAttributes, oHash:Refresh( .t. ) }
//
:CreateFromCode()
END
oWnd:oLeft := oBrw
@ 0,0 XBROWSE oHash OF oWnd DATASOURCE HB_Hash() NOBORDER CELL LINES
WITH OBJECT oHash
:nHeadStrAligns := AL_CENTER
:nWidths := 300
:nStretchCol := 2
//
:CreateFromCode()
END
oWnd:oClient := oHash
ACTIVATE WINDOW oWnd MAXIMIZED
RELEASE FONT oFont
return nil
static function XmlTree( cXml )
local oXmlDoc := TXmlDocument():New( cXml )
local oRoot := oXmlDoc:oRoot
local cPrompt := If( Empty( oRoot:cName ), cFileNoPath( cXml ), oRoot:cName )
local oTree
TREE oTree
TREEITEM cPrompt CARGO oRoot
if oRoot:oChild == nil
oRoot:cData := "BLANK XML FILE"
else
SubTree( oRoot:oChild )
endif
ENDTREE
oTree:Expand()
return oTree
static function SubTree( oNode )
TREE
do while oNode != nil
TREEITEM oNode:cName CARGO oNode
if oNode:oChild != nil
SubTree( oNode:oChild )
endif
oNode := oNode:oNext
enddo
ENDTREE
return nil
static function RClickMenu( oNode )
local oPop
MENU oPop POPUP 2007
MENUITEM "Path" ACTION msginfo( oNode:path() )
MENUITEM "Browse" ACTION XBrowse( oNode, oNode:path() )
MENUITEM "PrgGen" ACTION PrgGen( oNode )
ENDMENU
return oPop
static function PrgGen( oNode )
local cText := ""
if ValType( oNode:aAttributes ) == 'H'
HEVAL( oNode:aAttributes, { |cKey,uVal| ( ;
cText += PadR( " hRow:" + cKey, 24 ) + ' := :GetAttribute( "' + cKey + '" )' + CRLF ) } )
endif
if ! Empty( oNode:cData )
cText += PadR( " hRow:" + oNode:cName, 24 ) + ' := :cData' + CRLF
endif
if Empty( cText )
? "No prg"
else
cText := "WITH OBJECT oNode" + CRLF + cText + "END" + CRLF
MEMOEDIT( cText )
endif
return nil
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 8:28
von Manfred
HI Otto,
ich habe es versucht, aber nach ca 35 Minuten abgebrochen. In der Zeit hatte notepad++ es schon lange auf.
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 9:26
von azzo
Hallo Manfred,
danke.
Ich lese damit nur kleine Dateien von booking.com, etc. ein.
LG
Otto
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 12:06
von HaPe
Hallo Manfred !
Ich weiß nicht ob es dir hilft.
Zur Analyse von XML-Dateien verwende ich:
https://microsoft.github.io/XmlNotepad/
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 12:08
von Manfred
hm, es geht nicht um eine Analyse, sondern darum die DAten aus der XML Datei in eine Datenbank zu übernehmen.
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 12:19
von HaPe
Hallo Manfred !
Es gibt den kompletten Quellcode des Tools ...
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 18:15
von georg
Hallo, HaPe -
wo?
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 18:50
von Jan
Georg,
auf der Seite, die Hans-Peter verlinkt hat, ist auch ein Link zum Code.
Jan
Re: XML Dateien einlesen
Verfasst: Sa, 20. Aug 2022 20:28
von HaPe
- NotepadXML.jpg (207.87 KiB) 5563 mal betrachtet
Re: XML Dateien einlesen
Verfasst: So, 21. Aug 2022 9:56
von brandelh
Alles was die Datei direkt in den RAM lädt geht nicht wegen der Größe (mein MED liest bis 400 MB).
Aber auch die DBF hat ja seine Grenzen, wenn du in PostGreSQL oder andere SQL Server einlesen willst, gibt es eventuell dort einen Import.
Auf jeden Fall brauchst du eine Beschreibung der Daten, mit der kann man mit meiner TextReader dann zeilenweise die Daten einlesen und verarbeiten,
aber das ist dir ja zu umständlich
Re: XML Dateien einlesen
Verfasst: So, 21. Aug 2022 10:20
von Manfred
Hi Hubert,
nicht direkt so. Ich dachte nur es ging einfacher. Aber Deinen textreader würde ich schon ausprobieren wollen. Die DAtenbeschreibung habe ich dafür. Wobei der aber wikrlich Schritt für Schritt lesen muß. Alles auf einmal geht einfach nicht.....
Re: XML Dateien einlesen
Verfasst: Di, 23. Aug 2022 16:15
von Martin_L
Hallo Zusammen,
wir haben teilweise auch große XML-Dateien zu verarbeiten.
Xbase++ XmlSimpleParser() geht nicht wegen der Größe.
Xbase++ XMLDocProcess() oder Chillkat sind dafür zu langsam.
Daher haben wir den HBText-Reader etwas umgwandelt und lesen die Datei Blockweise in den Speicher und werten dann Zeilen(Tag)-weise aus.
Es gibt dabei analog zu XMLDocSetAction() jeweils den Start eines Blockes mit einem passenden Ende-Tag.
Der Teil dazwischen wird dann ausgewertet und verarbeitet.
Das funktioniert stabil und einigermaßen schnell. Zumindest schneller als die anderen Alternativen.