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. :roll:

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