Witam,
Potrzebuję pomocy w napisaniu czegoś na kształt parsera pliku XML. Przyznam szczerze, że nie wiem jak się za to zabrać. Potrzebuję odczytywać węzeł po węźle i zapisywać je do tabeli w bazie danych. childy, muszą wiązać się do parentów. Podpowie ktoś, jak to zacząć?
- Rejestracja:ponad 22 lata
- Ostatnio:minuta
- Postów:297
- Rejestracja:prawie 10 lat
- Ostatnio:5 minut
- Postów:1083
Robiłem coś podobnego. Jednak ja wczytywałem względnie małe dokumenty. Jedyne co mi było potrzebne, to komponent https://docwiki.embarcadero.com/Libraries/Athens/en/Xml.XMLDoc.TXMLDocument Po załadowaniu do komponentu pliku parsuje on i masz dostępne całe drzewo w postaci Node'ów https://docwiki.embarcadero.com/Libraries/Athens/en/Xml.XMLDoc.TXMLDocument.Node i każdy taki węzeł ma listę węzłów podrzędnych. Możesz przejść po wszystkich w głąb i dostaniesz się do każdego elementu.
Tylko przy kilku megabajtowych plikach wczytywanie może trochę (kilka sekund) trwać.
- Rejestracja:ponad 22 lata
- Ostatnio:minuta
- Postów:297
Wiesz. Tyle to ja wiem. Sam komponent TXMLDocument to ja znam. Chodzi o sam fakt odczytania poszczególnych węzłów i ich rodziców. Ale nie wartości, tylko nazw. A potem, żeby zapisywały się te nazwy węzłów do tabeli w bazie z odpowiednimi powiązaniami między sobą. Trzeba zacząć od tego, że aplikacja ma wczytywać plik, analizować jego strukturę, sprawdzić konkretną wartość z konkretnego węzła i jeśli struktura przypisana do tej wartości już istnieje w bazie, to będzie importować dane. A jeśli nie, to ma się zapisać kolejna struktura. Problemem jest to, że nie wiem jaki to plik. Wszystko ma robić praktycznie aplikacja. Rekurencja?
Żeby uściślić, to chodzi o to, jak zrobić rozpoznawanie ilości zagnieżdżeń we wczytanym pliku XML?
- Rejestracja:ponad 14 lat
- Ostatnio:około 2 godziny
Żeby uściślić, to chodzi o to, jak zrobić rozpoznawanie ilości zagnieżdżeń we wczytanym pliku XML?
Aby zapisać XML do tabeli taka informacja nie jest Ci zupełnie potrzebna
Później postaram się wrzucić jakiś przykład
- Rejestracja:ponad 14 lat
- Ostatnio:około 2 godziny
Przykład załadowania XML'a do datasetu.
Myślę że z zapisem do bazy dasz sobie radę.
xmlToDataset.zip
unit Unit4;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, math, strutils,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, generics.Collections, Vcl.ComCtrls, Data.DBXFirebird, Data.DB, Data.SqlExpr, Vcl.StdCtrls,
Xmldoc, xmlIntf, Vcl.Grids, Vcl.DBGrids, Datasnap.DBClient, midaslib;
type
TForm4 = class(TForm)
btnLoadFromXml: TButton;
ClientDataSet1: TClientDataSet;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
procedure btnLoadFromXmlClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
public
{ Public declarations }
Xmldoc: Ixmldocument;
procedure loadFromXml;
end;
var
Form4: TForm4;
id: integer;
const
xmlTxt = //
'<gridfiltr>' + #13 + //
'<gridname>GRID_MAG_V2_</gridname>' + #13 + //
'<filtername></filtername>' + #13 + //
'<hardfilters>' + #13 + //
'</hardfilters>' + #13 + //
'<predefinedfilters>' + #13 + //
'<simplefilter>' + #13 + //
'<active>1</active>' + #13 + //
'<or>1</or>' + #13 + //
'<filters>' + #13 + //
'<filtr>' + #13 + //
' <column></column>' + #13 + //
' <value></value>' + #13 + //
' <condition></condition>' + #13 + //
' <id>0</id>' + #13 + //
' <active>1</active>' + #13 + //
' <visible>1</visible>' + #13 + //
'</filtr>' + #13 + //
'<filtr>' + #13 + //
' <column></column>' + #13 + //
' <value></value>' + #13 + //
' <condition></condition>' + #13 + //
' <id>1</id>' + #13 + //
' <active>0</active>' + #13 + //
' <visible>1</visible>' + #13 + //
'</filtr>' + #13 + //
'<filtr>' + #13 + //
' <column></column>' + #13 + //
' <value></value>' + #13 + //
' <condition></condition>' + #13 + //
' <id>2</id>' + #13 + //
' <active>0</active>' + #13 + //
' <visible>1</visible>' + #13 + //
'</filtr>' + #13 + //
'<filtr>' + #13 + //
' <column></column>' + #13 + //
' <value></value>' + #13 + //
' <condition></condition>' + #13 + //
' <id>3</id>' + #13 + //
' <active>0</active>' + #13 + //
' <visible>1</visible>' + #13 + //
'</filtr>' + #13 + //
'<filtr>' + #13 + //
' <column></column>' + #13 + //
' <value></value>' + #13 + //
' <condition></condition>' + #13 + //
' <id>4</id>' + #13 + //
' <active>0</active>' + #13 + //
' <visible>1</visible>' + #13 + //
'</filtr>' + #13 + //
'</filters>' + #13 + //
'</simplefilter>' + #13 + //
'</predefinedfilters>' + #13 + //
'<browsefilters>' + #13 + //
'<column></column>' + #13 + //
'<filters>' + #13 + //
'</filters>' + #13 + //
'</browsefilters>' + #13 + //
'<softfilters>' + #13 + //
'<complexfilter>' + #13 + //
'<simplefilter>' + #13 + //
'<active>0</active>' + #13 + //
'<or>1</or>' + #13 + //
'<filters>' + #13 + //
'<filtr>' + #13 + //
' <column>STAN</column>' + #13 + //
' <value>0</value>' + #13 + //
' <condition>=</condition>' + #13 + //
' <id>0</id>' + #13 + //
' <active>0</active>' + #13 + //
' <visible>1</visible>' + #13 + //
'</filtr>' + #13 + //
'</filters>' + #13 + //
'</simplefilter>' + #13 + //
'</complexfilter>' + #13 + //
'</softfilters></gridfiltr>' + #13;
implementation
{$R *.dfm}
{ TelementsList }
function idGen: integer;
begin
inc(id);
result := id;
end;
{ TForm4 }
procedure addNodeToDataset(aDataset: Tdataset; aNode: Ixmlnode; aParentId: int64);
var
newId: int64;
i: integer;
begin
newId := idGen;
aDataset.Append;
aDataset.fieldbyname('id').asinteger := newId;
aDataset.fieldbyname('node_name').asstring := aNode.nodename;
if aNode.IsTextElement then
aDataset.fieldbyname('node_value').asstring := aNode.text;
aDataset.fieldbyname('parent_id').asinteger := aParentId;
aDataset.post;
for i := 0 to aNode.childnodes.count - 1 do
if aNode.childnodes[i].NodeType = tnodetype.ntElement then
addNodeToDataset(aDataset, aNode.childnodes[i], newId);
end;
procedure TForm4.btnLoadFromXmlClick(Sender: TObject);
begin
self.loadFromXml;
end;
procedure TForm4.FormCreate(Sender: TObject);
begin
self.Xmldoc := Txmldocument.Create(nil);
self.ClientDataSet1.fielddefs.add('id', ftlargeint);
self.ClientDataSet1.fielddefs.add('parent_id', ftlargeint);
self.ClientDataSet1.fielddefs.add('node_name', ftstring, 50);
self.ClientDataSet1.fielddefs.add('node_value', ftstring, 50);
self.ClientDataSet1.createdataset;
end;
procedure TForm4.loadFromXml;
begin
begin
self.ClientDataSet1.disablecontrols;
self.ClientDataSet1.open;
self.ClientDataSet1.emptydataset;
self.Xmldoc.XML.text := xmlTxt;
self.Xmldoc.Active := true;
addNodeToDataset(self.ClientDataSet1, self.Xmldoc.DocumentElement, 0);
self.ClientDataSet1.enablecontrols;
end;
end;
initialization
id := 0;
end.
- Przechwytywanie.JPG (75 KB) - ściągnięć: 2
Zarejestruj się i dołącz do największej społeczności programistów w Polsce.
Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.
MultiLine String
to fajna rzecz