Autor Beitrag
alex_id
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 73



BeitragVerfasst: Di 13.01.04 19:15 
Hallo,

also ich würde gern wissen wie ich aus einer XML Dateii die Anzahll der Einträge / Elemente auslesen kann, d. h. wenn ich zB ein xml file mit folgender Struktur habe :
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
<?xml version="1.0"?>
<data>
         <element>
             <wert>1</wert>
         </element>
         <element>
            <wert>2</wert>
         </element> 
</data>


.... möchte ich herauslesen wieviele elemente in diesem File sind.
PS: die Struktur ist nur ein Beispiel !!!

Danke

_________________
Es gibt viele Wege, doch man kann nur einen gehen!
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 14.01.04 09:50 
Das kommt auf den XML-Parser an, den du verwenden möchtest. Ab Delphi 6 ist eine XML-Komponente dabei. Da ich aber nur D5 habe, kann ich dazu nichts sagen.
Vor Delphi 5 kannst du im Web XML-Komponenten finden, oder du importierst die MS-XML-Typbibliothek. Zu letzterer kann ich allerdings was sagen :), weil ich sie schon benutzt habe. Nachdem du die XML-Datei geladen hast (Beispiele gibt´s dazu einige hier im DF), kommst du mit
ausblenden Quelltext
1:
xmldoc.documentElement					

an den Hauptknoten (bei dir "data") und mir
ausblenden Quelltext
1:
xmldoc.documentElement.childNodes.length					

an die Anzahl der Unterknoten ran. In dem Fall werden aber alle Knoten gezählt, auch wenn´s vielleicht so aussieht:
ausblenden Quelltext
1:
2:
3:
4:
5:
<data>
  <element/>
  <AndererName/>
  <element/>
</data>

Wenn du nur die "<element/>"-Knoten haben willst, kommst du mit XPATH und einer IXMLDOMNodeList-Variable am besten weg:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
nl := xmldoc.selectNodes('/data/element');
if(nl.length > 0then
begin
  { ... }
end;

Auch dazu müsstest du einige Beispiele finden. Und in der [url=www.delphipraxis.net/forum43_xml.html]DP[/url] gibt´s ´ne eigene XML-Sparte. Vielleicht wirst du da noch schneller fündig (Sorry an die hiesigen Mods und Admins).
alex_id Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 73



BeitragVerfasst: Mi 14.01.04 10:57 
Danke für die schnelle Hilfe ... werde es gleich mal testen ...
also ich hab folgendes probiert:
ausblenden Delphi-Quelltext
1:
2:
 Form1.xmlDoc.documentElement.selectNodes('element');
 length := Form1.xmlDoc.childNodes.length;

nur leider bekomme ich immer nur 2 als Anzahl zurück obwohl 4 einträge vorhanden sind ...

Ich such noch mal im Forum... aber wenn du noch eine Idee hast :?: :roll:

Danke noch mal :!:

Alex

_________________
Es gibt viele Wege, doch man kann nur einen gehen!
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 14.01.04 13:11 
Ich hoffe, du bist nicht der Meinung, dass
alex_id hat folgendes geschrieben:
ausblenden Quelltext
1:
2:
3:
<element>
  <!-- irgendwas dazwischen -->
</element>

zwei verschiedene Knoten sind? Wenn Ja, dann schäm dich! ;)

ausblenden Quelltext
1:
<element>					

ist der öffnende Knoten. Gemäß Konvention muss dieser Knoten aber auch wieder geschlossen werden. Das bedeutet, bei
ausblenden Quelltext
1:
</element>					

handelt es sich quasi immer noch um den gleichen Knoten. Und darum erhältst du IMHO auch den Wert 2, denn in deiner Beispieldatei gibt´s nur diese beiden "element"-Knoten. Das wird deutlicher, wenn die Knoten leer sind, dann kannst du die Datei nämlich auch so darstellen:
ausblenden Quelltext
1:
2:
3:
4:
<data>
  <element/>
  <element/>
</data>

Falls es nicht um dieses Beispiel aus deinem ersten Posting geht, dann schau mal vorsichtshalber wg. der Schreibweise. Evtl. ist ein kleiner Tippfehler im Knotennamen, bspw.
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
<data>
  <element/>
  <elemant/>
  <element/>
  <elemend/>
</data>

;)

Gruß.
alex_id Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 73



BeitragVerfasst: Mi 14.01.04 16:52 
nein ich habe das mit den Knoten schon verstanden (denke ich jedenfalls)
und meine Xml Datei sieht so aus :
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
<data>
  <element>
      <id>1</id>
  </element>
  <element>
      <id>2</id>
  </element>
  <element>
      <id>3</id>
  </element>
  <element>
      <id>4</id>
  </element>
</data>


und dennoch wird mir nur der Wert 2 zurückgegeben ...
was hab ich falsch gemacht ???

PS: ich bekomme auch den Wert 2 zurück wenn nur ein element enthalten ist ... ich finde das sehr werkwürdig :cry:

_________________
Es gibt viele Wege, doch man kann nur einen gehen!
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 14.01.04 19:11 
Was benutzt du eigentlich? Diese XML-Komponente von D6 und aufwärts, oder den MS-XML-Parser in Form der eingebundenen Typbibliothek? Ich werde bei Gelegenheit mal mit letzterem was versuchen und deine Beispieldatei benutzen, aber ich denke, ich bekomme das richtige Ergebnis.

Wenn sich also nicht irgendwo ein anderer Fehler eingeschlichen hat, dann sollte es aber in jedem Fall gehen - egal ob du nun die Komponente oder die Typbibliothek benutzt.
alex_id Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 73



BeitragVerfasst: Mi 14.01.04 20:13 
Ich benutze D6 und MS XML V4.0 ...

Ich erkläre mal was ich vorhabe ...
ich möchte aus einer XML Datei mit beliebiger Länge die Elemente auslesen und dazu im Programm dann ein Objekt anlegen welches dann die Werte aus der Datei bekommt um mit diesen im Programm arbeiten zu können :!:

Jedoch habe ich in der ganzen Sache noch keinen richtigen Fortschritte gemacht :cry: :evil:

Hast du Anregungen oder ein Beispiel ???

Danke

Moderiert von user profile iconPeter Lustig: Doppelpost gelöscht

_________________
Es gibt viele Wege, doch man kann nur einen gehen!
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 14.01.04 22:08 
Also jetzt mal ausgehend von deiner XML-Datei (s. Posting von 15 Uhr 52) habe ich mit dem MS-XML-4-Parser folgenden Code probiert:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
procedure TForm1.Button1Click(Sender: TObject);
var
  xmldoc : DOMDocument40;
  nl     : IXMLDOMNodeList;
  i      : integer;
begin
  xmldoc := CoDOMDocument40.Create;

  if(xmldoc <> nilthen
  try
    xmldoc.async := false;
    xmldoc.resolveExternals := false;

    if(xmldoc.load(ExtractFilePath(paramstr(0)) + 'test.xml')) then
    begin
      nl := xmldoc.documentElement.selectNodes('element');

      if(nl.length > 0then
      begin
        ListBox1.Items.Add(
          Format('%d gefundene Knoten',[nl.length]));
        ListBox1.Items.Add('');

        nl := xmldoc.selectNodes('/data/element/id');
        if(nl.length > 0then
          for i := 0 to nl.length - 1 do
            ListBox1.Items.Add(Format('%d. "element/id" hat den Wert "%s"',
              [i+1,nl.item[i].text]));
      end;
    end;
  finally
    xmldoc := nil;
  end;
end;

In der Listbox wird zuerst die Anzahl der gefundenen "element"-Knoten angezeigt, danach die einzelnen "id"-Werte. Das ist eigentlich auch der Grundcode, den ich beim Laden von XML-Dateien benutze. So wie oben zu sehen funktioniert´s bei mir auch. Ich erhalte die 4 als Ergebnis.

Du kannst mit XPath auch Spielereien machen, bspw.:
ausblenden Delphi-Quelltext
1:
2:
3:
nl := xmldoc.selectNodes('/data/element[id="2"]');
if(nl.length > 0then
  ShowMessage(nl.item[0].xml);

Musst du mal ausprobieren. ;) Oder schau mal ins Platform SDK von Microsoft. Wenn du XML 4 hast, dann müsstest du die entsprechende Hilfedatei aber auch haben. Kann ich nur empfehlen.

Gruß.
Miraculix
Hält's aus hier
Beiträge: 1

Win XP

BeitragVerfasst: Mo 19.01.04 14:36 
Hi an alle erst ma

In der Komponenten-palette gibt es die Komponente XML-Document.
da kannst du verschiedene Dinge auslesen

Mit XMLDocument1.DocumentElement liest du den OberKnoten aus in deinem Fall ist
DocumentElement: Data

um den Rest auszulesen könnest das so machen

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
var
  father, child: IXMLNode;
begin
  father := XMLDocument1.DocumentElement; 
  child := father.ChildNodes.First;                    //Erster Unterknoten 
  while child <> nil do                                  //solange es nen Knoten gibt
  begin

     child := child.NextSibling                    // Nächster Knoten der  Ebene   
  end;


um die ganze Hierarchie durch zugehen kannst du die While oder besser die Methode in die du die While Schleife schreibst rekursiv aufrufen

etwa so
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure XMLLesen(father: IXMLNode);
var
  child : IXMLNode;
begin
  child := father.ChildNodes.First;                             //Erster Unterknoten 
  while child <> nil do                                  //solange es nen Knoten gibt
  begin
     {Knoten Attribute ...  auslesen}
     XMLLesen(child);                                         //Rekursion der Prozedur
     child := child.NextSibling                    // Nächster Knoten der  Ebene   
  end;                                                                 //Ende While Schleife
end;                                                                   //Ende Prozedur


einfach fragen bei Unklarheiten :D

Moderiert von user profile iconUGrohne: Delphi-Tags hinzugefügt
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 19.01.04 15:25 
Warum so umständlich, Miraculix? Alex möchte bspw. wissen, wie viele Knoten namens "element" es in seiner XML-Datei gibt. Und das kannst du mit Hilfe des MS-XML-Parsers mit 2 Zeilen in Erfahrung bringen:
ausblenden Delphi-Quelltext
1:
2:
nl := xmldoc.documentElement.selectNodes('element');
ShowMessage(Format('%d gefundene Knoten',[nl.length]));

Voilà.

Ich bin mir ziemlich sicher, dass diese XML-Komponente von Delphi 6 (und höher) das auch kann. Bei deiner while-Idee müsste man nämlich noch prüfen, ob der Knotenname auch wirklich "element" lautet.

Wenn es dagegen nur um die Anzahl aller Knoten geht (egal welchen Namen sie tragen), dann genügt bspw.
ausblenden Delphi-Quelltext
1:
2:
ShowMessage(Format('%d gefundene Unterknoten',
  [xmldoc.documentElement.childNodes.length]));

Eine rekursive Funktion/Prozedur lässt sich ähnlich gestalten, so dass man relativ schnell die Anzahl aller Knoten, Unterknoten, Unterunterunter...knoten ermitteln kann, ohne deswegen die XML-Struktur einzeln durchlaufen zu müssen.

Das Einlesen bestimmter Knoten via XPath, etwa:
Zitat:
ausblenden Delphi-Quelltext
1:
nl := xmldoc.selectNodes('/data/element[id="2"]');					

ist ebenfalls eleganter und effizienter als alles der Reihe nach durchlaufen zu müssen. ;)
PeterPan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Do 14.07.05 14:28 
hallo,

gibt es eine doku zu xml und d7?

thx
pp
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 14.07.05 18:56 
Eine Doku zu XML wirst du nicht finden, weil der Inhalt von XML ganz dir überlassen bleibt. Wenn du eine Doku zu einem XML-Parser meinst, dann kommt es darauf an, mit welchem du arbeiten willst. Für diese TXmlDocument-Komponente von Delphi kann ich dir keins nennen. Für MS-XML gibt es nur eine Anlaufstelle: das MS-XML SDK/PSDK/MSDN.