XML - Datei einlesen und nach bestimmten Strings suchen

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Relexy18
Beiträge: 14
Registriert: Di 7. Mai 2019, 10:46

XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von Relexy18 »

Hallo Zusammen,

ich arbeite seit einiger Zeit mit Lazarus und muss damit XML-Dateien in ein Programm einlesen und nach bestimmten Kriterien auswerten.
Aufbau der XML-Datei Siehe Anhang (Maschinen Log Daten):
Bisher lade ich diese Datei in eine Stringliste geladen und gehe diese Zeile für Zeile durch, aber wenn ich mehere Dokumente habe die etwas größer sind, dann dauert dies teilweise ewig. Deswegen suche ich nach einen Plan B :)


Ich muss hier ein Programm schreiben, welches diese Daten Auswerten muss
z.B will ich die Anzahl der schon vorhandenen Bauteile die schon gelogt wurden rausbekommen
- Suchen nach Knotenpunkt "<Placement_INFO>" & <Measure_INFO> und die Anzahl aller Knotenpunkte zählen
- Werte rausfiltern <Die_Name>
- Werte rausfiltern <Batch_ID>
- Werte rausfiltern <Multiup_X>
- Werte rausfiltern <Multiup_Y>

WEnn die XML - Datei nur einen Main - Knotenpunkt hat, dann gehts es so
var
i,iC:integer;
s:string;
TestXML:TXMLDocument;
TestNode:TDOMNode;

begin
ReadXMLFile(TestXML,'R:\LogCount\Test\Test.xml');
edanz.Caption:=TestXML.DocumentElement.ChildNodes.Count.ToString;
if Edit1.Caption <>'' then begin
TestNode:= TestXML.DocumentElement.FindNode(Edit1.Caption);//Schlüsselwort suchen
edanz1.Caption:=TestNode.FirstChild.NodeValue;
end;

Jetzt meine Frage: wie bekomme ich das über die ganze Liste hin?
Dateianhänge
Test2.xml
Beispiel der XML Datei
(2.73 KiB) 165-mal heruntergeladen

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von wp_xyz »

Kann es sein, dass du die Original-Messdatei verändert hast, also den xml-Header und den TopLevel-Node entfernt hast? Wenn ja, poste bitte eine unbearbeitete Datei. Denn ReadXMLFile meldet bei mir: "Only one top-level element allowed"
z.B will ich die Anzahl der schon vorhandenen Bauteile die schon gelogt wurden rausbekommen"
in welchem Node ist ein Bauteil gespeichert?

Relexy18
Beiträge: 14
Registriert: Di 7. Mai 2019, 10:46

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von Relexy18 »

Danke für den Hinweis:
ja habe ich, da es nur symbolisch sein sollte. Ich schicke eine Orginaldatei aus der ich aber, wegen Datenschutz, pro Knoten zwei Zeilen löschen werde.

Danke Dir schon mal im Voraus! :D
Dateianhänge
071119-093554-00.xml
(390.52 KiB) 189-mal heruntergeladen

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von wp_xyz »

Leider verstehe ich die Fragestellung noch immer nicht. Aber vielleicht hilft dir folgender Beispiel-Code, der alle "Measure_INFO"-Nodes durchläuft, die "Date" und "Time"-Nodes ausliest und zusammen mit einer laufenden Nummer in einer Listbox ausgibt:

Code: Alles auswählen

uses
  [...], laz2_dom, laz2_xmlread;
 
function GetNodeValue(ANode: TDOMNode): String;
var
  child: TDOMNode;
begin
  Result := '';
  if ANode <> nil then begin
    child := ANode.FirstChild;
    if child <> nil then Result := child.NodeValue;
  end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
  doc: TXMLDocument = nil;
  mi_node: TDOMNode;
  d_node: TDOMNode;
  t_node: TDOMNode;
  s: String;
  n: Integer;
begin
  Listbox1.Items.Clear;
  Listbox1.Items.BeginUpdate;
  try
    n := 0;
    ReadXMLFile(doc, '071119-093554-00.xml');
    try
      mi_node := doc.DocumentElement.FindNode('Measure_INFO');
      while mi_node <> nil do begin
        d_node := mi_node.FindNode('Date');
        t_node := mi_node.FindNode('Time');
        if (d_node <> nil) and (t_node <> nil) then begin
          inc(n);
          s := Format('%d: %s %s', [n, GetNodeValue(d_node), GetNodeValue(t_node)]);
          Listbox1.Items.Add(s);
        end;
        mi_node := mi_node.NextSibling;
      end;
    finally
      doc.Free;
    end;
  finally
    Listbox1.Items.EndUpdate;
  end;
end;

Relexy18
Beiträge: 14
Registriert: Di 7. Mai 2019, 10:46

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von Relexy18 »

Vielen Dank für Deine Hilfe!

Ja ich muss zugeben, dass ich mich etwas verwirrt ausgedrückt habe, aber ich glaub du hast mir auf jeden Fall weitergeholfen. Ich hab genau so etwas gesucht.

Eine Frage noch folgende Funktion => gibt es da auch einen Counter, um festzustellen wie viel solcher Elemente im gesamten XML - File vorhanden sind?

Z.B.
[list]mi_node := doc.DocumentElement.FindNode('Measure_INFO').Count; //Anzahl bestimmen dieser Elemente bzw. Knotenpunkte

d_node := mi_node.FindNode('Date').Count Anzahl bestimmen aller DATES im "Measure_INFO" und "Placement_INFO" - Knoten vom gesamten File

Hintergrund:
das Logfile wird ständig überschrieben mit neuen Einträgen. Meine Aufgabe ist eine Art Dashboard zu erstellen, in dem folgende Werte enthalten sind.
- Wieviel BT im Modul und im gesamten Auftrag sind schon platziert.
- Dauer der Laufzeit
- Akuteller ARbeitsschritt "Messen" oder "Placement"
- aktuelle SN in Bearbeitung
- aktuelles BT in Bearbeitung

Falls nicht, werde ich einfach die gefundenen Node in eine Stringliste packen und dort den .count benutzen.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von wp_xyz »

Relexy18 hat geschrieben:Gibt es da auch einen Counter, um festzustellen wie viel solcher Elemente im gesamten XML - File vorhanden sind?
Z.B.
[list]mi_node := doc.DocumentElement.FindNode('Measure_INFO').Count; //Anzahl bestimmen dieser Elemente bzw. Knotenpunkte

Es gibt ein GetChildCount, das die Anzahl der Kind-Knoten ermittelt.

Relexy18 hat geschrieben:Falls nicht, werde ich einfach die gefundenen Node in eine Stringliste packen und dort den .count benutzen.

Das ist viel zu aufwending. Durchlaufe einfach in einer while-Schleife, wie in meinem Beispiel gezeigt, alle Knoten und lasse einen Zähler mitlaufen.

Timm Thaler
Beiträge: 1224
Registriert: So 20. Mär 2016, 22:14
OS, Lazarus, FPC: Win7-64bit Laz1.9.0 FPC3.1.1 für Win, RPi, AVR embedded
CPU-Target: Raspberry Pi 3

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von Timm Thaler »

Relexy18 hat geschrieben:Ich schicke eine Orginaldatei aus der ich aber, wegen Datenschutz, pro Knoten zwei Zeilen löschen werde.


Das ist auch keine gültige XML, eine XML fängt immer mit der Deklaration an: <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

Sonst kann der Parser zu Recht meckern, und spätestens wenn Du Umlaute drin hast fliegt Dir das um die Ohren, wenn der Parser das falsche Encoding annimmt.

Ein Tipp noch: Wenn die XML Dateien UTF-8 sind, unbedingt wie im wp_xyz Beispiel die laz2_dom, laz2_xml... Libs nehmen, die originalen XML Libs kommen mit UTF-8 nicht klar.

Relexy18
Beiträge: 14
Registriert: Di 7. Mai 2019, 10:46

Re: XML - Datei einlesen und nach bestimmten Strings suchen

Beitrag von Relexy18 »

Vielen Dank für die hilfreichen Informationen. Damit werde ich wohl erst einmal weiterkommen.

Antworten