![]() |
XML Daten in DB importieren
Hallo DPler :hi:
Ich sitze grade vor einem Problem was mir üble Kopfschmerzen bereitet. Ich muss ca. 450.000 Zeilen XML Daten in eine DB haben. Es sollte eine Embedded DB sein. Welche is mir im Moment wurscht (SQLite, Firebrid etc.). Die Daten haben folgende Struktur:
XML-Code:
Wobei das nur ein SubNode ist.
<ROOT>
<Node value="E31"> <Node value="ABGB-C02" /> <Node value="ABGZ-C01" /> <Node value="ASC5-C01" /> <Node value="ASC5-C06" /> <Node value="DSC-C01" /> <Node value="DWA3-C25" /> <Node value="DWA4-C27" /> <Node value="EDC3-C00" /> <Node value="EDC3P-C25" /> <Node value="EKM-C00" /> <Node value="EKM-C01" /> <Node value="EKM-C25" /> <Node value="EML-C01" /> <Node value="EWS-C01" /> <Node value="EWS-C02" /> <Node value="GM2-C25" /> <Node value="LKM2-C25" /> <Node value="LSM-C25" /> <Node value="ZAE2-C03" /> <Node value="ZAE2-C05" /> </Node> <--!Viele Subnodes weiter--> </ROOT> Es gibt noch eine andere Variante (das ist der Aufbau der meisten Daten(~90%)):
XML-Code:
Ich hatte erst versucht die Daten so zu nutzen aber das ist absolut inakzeptabel von der Geschwindigkeit her.
<ROOT>
<E31ASC5-C06 value="ASC5-C06"> <FSW value="MRA_TAKTUNG"> <PSW value="aktiv"/> <PSW value="nicht_aktiv"/> </FSW> <FSW value="LASTBEREICHSKENNFELD"> <PSW value="aktiv"/> <PSW value="nicht_aktiv"/> </FSW> <FSW value="SCHLUPFSCHWELLENOFFSET"> <PSW value="aktiv"/> <PSW value="nicht_aktiv"/> </FSW> <FSW value="GETRIEBE"> <PSW value="automatik"/> <PSW value="handschaltung"/> </FSW> <FSW value="BMR_TYP"> <PSW value="typ_1"/> <PSW value="typ_2"/> <PSW value="typ_3"/> </FSW> <FSW value="AMR_TYP"> <PSW value="typ_1"/> <PSW value="typ_2"/> <PSW value="typ_3"/> </FSW> <FSW value="SCHLUPFBANDMODIFIKATION"> <PSW value="nicht_aktiv"/> <PSW value="absenkung_0.5_km/h"/> </FSW> <FSW value="MRAGRENZ"> <PSW value="wert_01"/> </FSW> <FSW value="KURVENLOGIK"> <PSW value="typ_1"/> <PSW value="typ_2"/> <PSW value="typ_3"/> </FSW> </E31ASC5-C06> <--!Viele Subnodes weiter--> </ROOT> Man meint das die Daten aus dem Web geladen werden und nicht direkt von der Platte :? Jetzt suche ich eine Möglichkeit diese Daten möglichst einfach in eine Datenbank zu bringen. Erste versuche mit Access sind kläglich gescheitert. Insgesamt Teilt sich die Datenmenge auf 18 Solcher Dateien auf. Die zentrale Liste hat das zu erst gepostete Format die anderen 17 das zweite Format. Wie kann ich nun das ganze am schnellsten in Tabellen bringen? Mit den <Node> Elementen habe ich bisher ein Treeview gefüllt. Das wollte ich auch gern bei behalten. Für die Bereiche <FSW> sowie <PSW> ist jeweils eine ListBox vorgesehen. Hier wäre es optimal wenn die ID der FSW mit dem Index in der Listbox übereinstimmt damit ich darüber die passenden <PSW> Elemente finde. Als XML Parser habe ich ADOM (OpenXML) im einsatz. Damit komme ich auch gut klar aber die Geschwindigkeit ist unzumutbar für Anwender. Ich wäre dankbar wenn mir jemand etwas Hilfe bei der Umsetztung geben könnte da XML immer noch nich so ganz meins ist :stupid: |
Re: XML Daten in DB importieren
Hallo...
ich benutze für so etwas SimpleXML von den Jedis. Dann schreibe ich mir passend zu den Daten eine procedure, welche die Daten in die Datenbank einträgt (eventuell noch mit Informationen welche nicht im XML stehen). ...das ist aber auch keine schnelle Variante. Wie oft mußt du die XML einlesen ?. Ich brauche, da das Einlesen / Konvertieren in 2 Schleifen abläuft, für 40000 Datensätze ca. 20-30 Sekunden. :hi: PS: ich bin bekennender Firebird Fan...deshalb dieses als Empfehlung :P |
Re: XML Daten in DB importieren
Wie lange das braucht ist mir egal.
Da ich die Daten nur einmal da rein bringen muss danach kann ich die Updates direkt machen. Ich werde mir das mit den Jedis mal anschauen danke für den Tipp. Hast du eventuell noch ne kleine Anleitung zu dem ganzen damit ich mich mal einlesen kann? Habe bisher die Jedis nicht genuzt. |
Re: XML Daten in DB importieren
...ich zeige dir einfach mal eine procedure :wink:
Delphi-Quellcode:
// Import XML Gebührenordnung
procedure TDMDB.XMLImportGE; var AnzahlDS: Integer; A: Integer; I: Integer; Inhalt: TStringList; begin Inhalt:= TStringList.Create; try JvSimpleXML1.FileName:= InstallPfad + 'GE.xml'; AnzahlDS:= JvSimpleXML1.Root.Items.Item[1].Items.Count; if Start then begin Splash.JvXPProgressBar1.Max:= AnzahlDS; Splash.JvXPProgressBar1.Position:= 0; Splash.JvLabel1.Caption:= 'Import GebüH...'; end; Splash.JvXPProgressBar1.Refresh; Splash.JvLabel1.Refresh; for A:= 0 to AnzahlDS -1 do begin try Inhalt.Clear; Splash.JvXPProgressBar1.Refresh; for I:= 0 to 2 do begin Inhalt.Add(JvSimpleXML1.Root.Items.Item[1].Items.Item[A].Items.Item[I].Value); end; ZQueryDiv.SQL.Text:= 'insert into GEBUH (GRUPPE,UNTERGRUPPE,TEXT,GEBUHID,LEISTUNG,NUMMER,ICON) values '; ZQueryDiv.SQL.Add('(:Gruppe,:Untergruppe,:Text,:GebuhID,:Leistung,:Nummer,:Icon)'); ZQueryDiv.ParamByName('Gruppe').Value:= A+2; ZQueryDiv.ParamByName('Untergruppe').Value:= 1; ZQueryDiv.ParamByName('Text').Value:= Inhalt.Strings[2] + ' ' + Inhalt.Strings[1]; ZQueryDiv.ParamByName('GebuhID').Value:= StrToInt(Inhalt.Strings[0]); ZQueryDiv.ParamByName('Leistung').Value:= Inhalt.Strings[1]; ZQueryDiv.ParamByName('Nummer').Value:= Inhalt.Strings[2]; ZQueryDiv.ParamByName('Icon').Value:= 2; ZQueryDiv.ExecSQL; except FehlerCode:= 'E422'; Fehlerstatus:= False; Fehlertext:= 'Import der GebüH fehlgeschlagen. '; raise; end; if Start then Splash.JvXPProgressBar1.Position:= A; Splash.JvXPProgressBar1.Refresh; end; finally Inhalt.Free; end; try if FileExists(InstallPfad + 'GE.xml') then DeleteFile(InstallPfad + 'GE.xml'); except FehlerCode:= 'E421'; Fehlerstatus:= True; Fehlertext:= 'Löschen der Datei GE.xml fehlgeschlagen. '; raise; end; FGebuH.GEBUHEinlesen; end;
Delphi-Quellcode:
...mit diesem Part mußt du dann etwas experimentieren entsprechend der Struktur deiner XML.
Inhalt.Add(JvSimpleXML1.Root.Items.Item[1].Items.Item[A].Items.Item[I].Value);
Der Ablauf ist im Prinzip folgender: - 1. Schleife A -- Anzahl der Datensätze / Nodes - 2. Schleife I -- Schreibt die Values des Nodes in eine StringList, I(MAX) entspricht der Menge der Values in der StringList (in diesem Falle 2..bei dir vieleicht anders) - 3. Insert in DB mit den Werten der StringList ....usw. viel Spaß... :wink: |
Re: XML Daten in DB importieren
Danke dir.
Das sieht relativ einfach aus. Hatte schon den Verdacht das mich das einige graue Haare kosten würd aber damit sieht es im Moment sehr einfach aus. :dp: Herzlichen Dank :cheers: |
Re: XML Daten in DB importieren
PS: du kannst die Nodes in der XML auch anders identifizieren. Schaust du einfach was JvSimpleXML dir an Propertys bietet. Für mich bot sich ITEMS an, da ich das dann gut über den Index in der Schleife verarbeiten kann.
PS1: den ganzen Visualisierungskram kannst du ja weg lassen... :P :hi: |
Re: XML Daten in DB importieren
Ok werd mal reinschauen :)
Muss erstmal die Jedis Installieren :) |
Re: XML Daten in DB importieren
So das mit dem Items identifizieren is mir nun klar.
Geht über Item[index] oder ItemNamed[name]. Aber wie komme ich an die Attribute des Items? Die Methodenliste gibt da nix her :( |
Re: XML Daten in DB importieren
ich denke daß du...
Item[x].Value meinst. Das repräsentiert den Wert deines ItemNamed['blabla'] oder dein ItemNamed['blabla'] hat wieder Items.Item[x].Value je nach Verzweigung deiner Vorlage. :hi: |
Re: XML Daten in DB importieren
Hatte einen test gemacht mit einem Memo.
Delphi-Quellcode:
Nur bleibt das Memo leer :wiejetzt:
OpenDialog1.Execute();
if OpenDialog1.FileName <> '' then begin JvSimpleXml1.FileName := OpenDialog1.FileName; for I := 0 to JvSimpleXML1.Root.Items.Item[0].Items.Count - 1 do Memo1.Lines.Add(JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Value) end; Edit: Er findet auf jeden Fall Items da I > 0 ist ;) Hab ich grad noch mal im Debug gecheckt. Noch mal Edit: Nu passiert was :idea: Aber die ausgelesenen Strings sind leer :wiejetzt: Haha rate mal ein Edit: So gehts:
Delphi-Quellcode:
var
I: Integer; begin OpenDialog1.Execute(); if OpenDialog1.FileName <> '' then begin JvSimpleXML1.LoadFromFile(OpenDialog1.FileName); for I := 0 to JvSimpleXML1.Root.Items.Item[0].Items.Count - 1 do Memo1.Lines.Add(JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Properties.Value('value')); end; end; |
Re: XML Daten in DB importieren
ah jetzt ja.... :gruebel:
Zitat:
|
Re: XML Daten in DB importieren
Jetzt muss ich nur noch die embedded DB zum laufen bekommen -.-
Mal sehen wie lang ich dafr brauch :roll: |
Re: XML Daten in DB importieren
fbclient.dll
firebird.conf firebird.msg icudt30.dll icuin30.dll icuuc30.dll ...diese Dateien ins Anwendungsverzeichnis - DB mit z.B. IBExpert erstellen - DB in beliebiges Verzeichnis - Connection abhängig von Zugriffskomponenten Tipps für Zeos: - Host muß ein Leerstring sein '' - User und Paßwort zuweisen (Standard: SYSDBA / masterkey) - Database: lokaler Ordner wo die Datenbank liegt. :hi: |
Re: XML Daten in DB importieren
Ne ich hab mich für DISQLite3 und SQLite3.dll entschieden :)
Der Fehler war die ganze Zeit im Statement habs nur vor blindheit nich gesehen :oops: |
Re: XML Daten in DB importieren
...viel Spaß beim Entdecken der unbekannten Möglichkeiten. :P
|
Re: XML Daten in DB importieren
Unbekannt sind die nicht :)
Hab sqlite3 schon in einem .Net Projekt im Einsatz :) Aber die Geschwindigkeit wird schön. Muss ich nur noch die Routine für den Import der anderen Daten schreiben. Hab gesehen das die JVCL ein DBTreeView liefert :) Muss ich das auch nimmer suchen :stupid: Danke nochmal für deine Hilfe :) |
Re: XML Daten in DB importieren
Zitat:
...hier habe ich mal erklärt worauf es ankommt. ![]() :hi: |
Re: XML Daten in DB importieren
Ui du bist mein Held heute :)
Im Hintergrund rattert die Festplatte weil durch deine Hilfe das ganze sehr einfach geworden ist :) Ich hoffe das ich das ganze dann heut abend noch in die DB bekomme :D Dann hab ich nen großen vortschritt gemacht was Wissen und Projekt angeht :) :dp: :dp: |
Re: XML Daten in DB importieren
...und ich habe meine guten Taten für dieses Jahr weg... :mrgreen: :cheer:
|
Re: XML Daten in DB importieren
Und ich tu auch noch eine :)
Hier die Routine die ich nun zusammen gestellt habe. Falls jemand das gleiche bzw ein ähnliches Problem hat kann er sich daran orientieren :)
Delphi-Quellcode:
Noch eine kurze anmerkung:
procedure TForm2.xml_batch(FileName: string);
var tblName: string; FSW: string; B: Integer; I: Integer; PSW: string; A: Integer; begin JvSimpleXML1.LoadFromFile(FileName); for I := 0 to JvSimpleXML1.Root.Items.Item[0].Items.Count - 1 do begin tblName := ''; PSW := ''; FSW := ''; tblName := StringReplace(JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Name, '-', '_', [rfReplaceAll]); DISQLite3db.Execute16('CREATE TABLE [' + tblName + '] ([ID] INTEGER NOT NULL PRIMARY KEY,[FSW] TEXT NOT NULL,[PSW] TEXT NULL,[COMMENT] TEXT NULL)'); for A := 0 to JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Items.Count - 1 do begin FSW := JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Items.Item[A].Properties.Value('value'); for B := 0 to JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Items.Item[A].Items.Count - 1 do begin PSW := PSW + JvSimpleXML1.Root.Items.Item[0].Items.Item[I].Items.Item[A].Items.Item[B].Properties.Value('value') + #10; end; DISQLite3db.Execute16('INSERT INTO ' + tblName + ' VALUES (NULL,"' + FSW + '","' + PSW + '", "")'); end; end; end; Ich habe wie schon erwähnt SQLite3 im einsatz.
Code:
Bewirkt bei SQLite3 ein Integerfeld mit Autoincrement :)
[ID] INTEGER NOT NULL PRIMARY KEY
|
Re: XML Daten in DB importieren
Zitat:
...siehe kurze Erklärung in #17. Weil ohne die 2 Integer Felder kann der DBTreeView den Baum nicht darstelllen. PS: für JvDBTreeview1.MasterField kannst du auch dein ID Feld benutzen, da es ja eh eine laufende Nummer darstellt. :hi: |
Re: XML Daten in DB importieren
Das ist nur die Routine für den zweiten XML abschnitt im eingangs Posting ;)
Die TreeView Tabelle hat ein ID Feld und ein Parent_ID Feld. Root = 0 E31 = 1 usw. So hat E31 Parent_ID 0 Und alle unterbereiche von E31 Parent_ID = 1 Dürfte so gehen oder? Hab den Link erst gesehen nach dem die Daten in der DB waren :stupid: Aber das dauert 20sec die Daten neu zu laden falls es nicht passt. |
Re: XML Daten in DB importieren
Zitat:
|
Re: XML Daten in DB importieren
Hehe und das ohne vorher zu wissen das es so sein muss :mrgreen:
Selbstständiges denken liegt mir irgendwie. Vielleicht war ich deswegen nich beim Bund :corky: Dann hab ich nun alles zusammen und werd den Thread als gelöst markieren :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz