Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Xml (https://www.delphipraxis.net/154484-xml.html)

value is NULL 13. Sep 2010 08:35


Xml
 
Hi

Ich weiß das Thema wurde schon X mal angesprochen ,versucht zu erklären usw bin jetzt 2 Tage an google gesessen und konnte das "Problem" leider immer noch nicht lösen :(

ich habe folgendes XML und bin ziemlich neu in dem Bereich:
XML-Code:
<config>
   <virtualdrive1>
      <maxsize>700</maxsize>
      <validfrom>YYYY-mm-dd hh:mm:ss.999</validfrom>
      <validto>YYYY-mm-dd hh:mm:ss.999</validto>
      <example>
          <ex1>example</ex1>
          <ex1>example</ex2>
      </example>
      <share>
      <shareuser>user</shareuser>
      <sharepw>sharepw</sharepw>
      <sharepath>sharepath</sharepath>
      </share>
   </virtualdrive1>
</config>
Was ich so ergooglet habe muss ich ich das ganze in einen DOM einlesen, ich weiß aber leider nicht wie das funkt, hab was gelesen vonwegen SimpleXML und XDOM aber ich komm mit den beschreibungen im Netz
nicht wirklich klar

könnt ihr mir da helfen ?

Danke schon mal im voraus und LG

stahli 13. Sep 2010 08:51

AW: Xml
 
Hallo Value,

es gibt hier ein XML-Unterforum, da findest Du sicher einige Hinweise.
Hier habe ich mal versucht, eine kleine Einstiegshilfe zu geben...

value is NULL 13. Sep 2010 09:00

AW: Xml
 
hi stahli

Das sieht ja sehr gut aus, ich habe aber das Problem, das ich das ganze auf Console app basis mache.
Dh. ich müsste theoretisch (das sind jetzt spekulationen :) ) :
- xml zu uses hinzufügen
- das xml deklarieren myxml : TXMLDocument;
- myxml.loadfromfile('C:\myxml.xml');

aber dann weiß ich nicht weiter, es gibt kein "DocumentElement" :(

gibt es da eine andere möglichkeit?

LG

himitsu 13. Sep 2010 11:04

AW: Xml
 
Zitat:

Zitat von value is NULL (Beitrag 1049170)
- xml zu uses hinzufügen
- das xml deklarieren myxml : TXMLDocument;

TXMLDocument steckt in der Unit XMLDoc.

Und wenn du mal nach deinem verwendeten Hier im Forum suchenTXMLDocument in der DP suchst, dann wirst du auch unmassen Threads finden, in welchen dieses verwendet wird und da hätte man mal abgucken können.
z.B. in http://www.delphipraxis.net/136812-t...d-umlaute.html

Zitat:

Zitat von value is NULL (Beitrag 1049170)
aber dann weiß ich nicht weiter, es gibt kein "DocumentElement"

Und wenn du wirklich
Delphi-Quellcode:
myxml : TXMLDocument
verwendet hast, dann gibt es gibt es das definitiv.

samso 13. Sep 2010 11:24

AW: Xml
 
So, oder ähnlich funktioniert das mit allen XML-Komponenten - Beispiel:
Delphi-Quellcode:
program Test1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  SimpleXML;

var
  myConfig: IXmlDocument;

begin
  try
    myConfig := LoadXmlDocument('C:\myxml.xml');
    WriteLn(myConfig.SelectSingleNode('config\virtualdrive1\maxsize').Text);
    ReadLn;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Ausgabe ist dann "700"

Achtung Beispieldatei ist fehlerhaft!
statt: <ex1>example</ex2>
wäre richtig: <ex2>example</ex2>

cookie22 13. Sep 2010 11:44

AW: Xml
 
das kommt wohl ganz auf die xml compo/unit an. ;)

value is NULL 13. Sep 2010 12:03

AW: Xml
 
danke für die antworten...

hab das mit SimpleXML probiert ich habe aber keine function mit selectsinglenode. habe es deshalb mal mit XML versucht:

Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  xml;

var
  a : TXmlDocument;

begin
  try
        a.LoadFromFile('C:\config.xml');
        Writeln(a.GetTag('config\param').CData);
  except
       on e : exception do begin
                            writeln(e.message);
                            halt(1);
                        end;
  end;

end.


bekomme aber immer eine exception :(

stahli 13. Sep 2010 12:16

AW: Xml
 
Schau mal hier im Beitrag #7, ob das etwas hilft...

himitsu 13. Sep 2010 12:21

AW: Xml
 
Zitat:

Zitat von value is NULL (Beitrag 1049215)
bekomme aber immer eine exception :(

Ja, wenn man vergißt das XMLObjekt zu erstellen, dann ist das kein Wunder.

Wobei es immer schön wäre, wenn man den "Text" der Exceptions erfährt.
Meine :glaskugel: vermutet aber was mit "Zugriffsverletzung auf Adresse $000000xx".

PS: In meinem himXML-Download befinden sich ein paar Demos und in der CheckLibs.dpr gibt es, unter Anderem, auch einige Beispiele für SimpleXML.


OK, SimpleXML ist etwas anders aufgebaut, da könnte das mit dem DOMDocument stimmen.
Wobei dein Delphi auch MSXML enthält > TXMLDocument aus der Unit XMLDoc.


@stahli: SimpleXML und XPath?

value is NULL 13. Sep 2010 12:34

AW: Xml
 
ah ok, habe jetzt mal folgendes versucht:

Delphi-Quellcode:
var
a : TXmlDocument;

begin
  try
          a := TXMLDocument.Create;
          a.LoadFromFile('C:\config.xml');
          Writeln(a.GetTag('config\param').CData);
  except
          on e : exception do begin
          writeln(e.message);
          halt(1);
          end;
  end;

end.

und bekomme folgendes zurück:

Fehler beim Parsen von Datei 'config.xml' (Zeile 3, Zeichen 9): '<' erwartet, aber '1' gefunden

was meint er damit? mein XML sieht so aus:

<config>
<param>123</param>
</config>

value is NULL 13. Sep 2010 13:20

AW: Xml
 
so, bin jetzt glaub ich?! ein stück weiter:

Delphi-Quellcode:
uses
  SysUtils,
  xmldoc;

var
a : TXmlDocument;

begin
  try

          a := TXMLDocument.Create(nil);
          a.Active := True;
          a.LoadFromFile('C:\test.xml');

  except
          on e : exception do begin
          writeln(e.message);
          a.Destroy;
          halt(1);
          end;
  end;

end.
jetzt bekomme ich aber die Meldung: CoInitialize wurde nicht aufgerufen.

habe gelesen das ich das for das am anfang und am ende setzen muss. jedoch sagt er mir immer undeclared identifier...
Bin ich am richtigen weg oder am komplett falschen? :)

LG

himitsu 13. Sep 2010 13:36

AW: Xml
 
Nja, SimpleXML ist halt ein bissl "älter", obwohl ich jetzt nicht wüßte, warum es mit dieser Datei nicht klarkommen sollte.
Wobei die 1 für micht in Zeile 2 Zeichen 8 liegt. :gruebel:

PS: Hier im Forum suchenCoInitialize wurde nicht aufgerufen

Und dann ruft man Destroy eigentlich nicht direkt auf, sondern nutzt Free.

value is NULL 13. Sep 2010 13:40

AW: Xml
 
hm naja ich machs ja jetzt nicht mit SimpleXML sonder mit XMLDoc dh:

Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  xmldoc;

var
a : TXmlDocument;

begin
  try

          a := TXMLDocument.Create(nil);
          a.Active := True;
          a.LoadFromFile('C:\test.xml');

  except
          on e : exception do begin
          writeln(e.message);
          a.Free;
          halt(1);
          end;
  end;

end.
habe versucht das Coinitialize fast an jeder Stelle des codes zu platzieren, das will er aber niergends...
wo gehört das den hin?

LG

DeddyH 13. Sep 2010 14:06

AW: Xml
 
Versuch es einmal im Initialization-Abschnitt. Und Du gibst a nur im Falle einer Exception frei, das soll ja bestimmt nicht so, oder?

value is NULL 13. Sep 2010 14:18

AW: Xml
 
hm da liegt ja momentan mein problem, habe sowas bis dato noch nie benötigt und jetzt steh ich ziemlich an.
ausserdem war das dann ja noch nicht alles, schließlich will ich mir ja noch den wert 123 von param auslesen... :(

kann mir jemand helfen?

Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  xmldoc,
  xmlintf;

var
a : TXmlDocument;

begin
  try
          a := TXMLDocument.Create(nil);
          a.Active := True;
          a.LoadFromFile('C:\test.xml');
  except
          on e : exception do begin
          writeln(e.message);
          halt(1);
          a.Free;
          end;
  end;

  a.Free;
end.

value is NULL 13. Sep 2010 14:37

AW: Xml
 
so... ich glaube ich komme meiner sache näher... habe jetzt ActiveX hinzugefügt und siehe das funkt!

Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  xmldoc,
  xmlintf,
  activex;

var
a : TXmlDocument;

begin
  try
          CoInitialize(nil);
          a := TXMLDocument.Create(nil);
          a.Active := True;
          a.LoadFromFile('C:\test.xml');
  except
          on e : exception do begin
          writeln(e.message);
          a.Free;
          halt(1);
          end;
  end;

  a.Free;
  CoUninitialize;
end.
jetzt muss ich mir nur noch den Wert auslesen, hat da jemand ein Beispiel für mich?

samso 13. Sep 2010 15:04

AW: Xml
 
mit der XML Datei:
Code:
<config>
   <virtualdrive1>
      <maxsize>700</maxsize>
      <validfrom>YYYY-mm-dd hh:mm:ss.999</validfrom>
      <validto>YYYY-mm-dd hh:mm:ss.999</validto>
      <example>
          <ex1>example</ex1>
          <ex2>example</ex2>
      </example>
      <share>
      <shareuser>user</shareuser>
      <sharepw>sharepw</sharepw>
      <sharepath>sharepath</sharepath>
      </share>
   </virtualdrive1>
</config>
Delphi-Quellcode:
  SysUtils,
  ActiveX,
  XMLIntf,
  xmldoc;

var
  myConfig: IXMLDocument;
begin
  try
    CoInitialize(nil);
    myConfig := LoadXmlDocument('Config.xml');
    WriteLn(myConfig.DocumentElement.ChildNodes.First.ChildNodes.First.Text);
    ReadLn;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;

value is NULL 13. Sep 2010 16:03

AW: Xml
 
das funktioniert! unglaublich! xD

ein Problem habe ich jedoch noch:

wenn ich versuche den Shareuser auszulesen bekomme ich folgende Exception:

Access violation at address 00416243 in module 'test.exe'. Read of address 00000000

Code ist wie folgt:

Delphi-Quellcode:
try
                      CoInitialize(nil);
                      config := LoadXMLDocument('C:\test.xml');
                      filesize := config.DocumentElement.ChildNodes.First.ChildNodes.First.Text;
                      shareuser := config.DocumentElement.ChildNodes.FindNode('shareuser').Text;
except
                      on e : exception do begin
                      writeln(e.message);
                      end;
                  end;
wobei filesize und shareuser ein string sind....
muss ich davor ein Release machen oder irgendwas in der art?

Kalakmul 13. Sep 2010 16:54

AW: Xml
 
Wenn ich es richtig sehe, versuchst Du "shareuser" in der obersten Knotenebene der Hierarchie zu finden, wo es aber nur "virtualdrive" gibt. Das ist wahrscheinlich die Ursache für die Fehlermeldung.

Du müsstest erst in einer Knotenvariable z. B. "ANode: IXMLNode;" den Knoten speichern, unterhalb dessen Du suchen willst, und dann mit "ANode.FindNode('shareuser')" weitersuchen.

Hier: http://wiki.freepascal.org/XML_Tutorial habe ich ein ganz gutes Tutorial gefunden, das Dir vielleicht weiterhilft.

Hier: http://delphi.about.com/od/interneti...rss_read_3.htm findest Du auch ein wenig Quellcode, der die Verwendung von Nodes verdeutlicht (auch wenn es inhaltlich um RSS-Feeds geht).

Ich hoffe, dass Dir das weiterhelfen kann.

value is NULL 14. Sep 2010 08:20

AW: Xml
 
Hi

vielen dank, bin jetzt ein großes Stück weiter!!

und zwar habe ich folgendes XML:

Code:
<config>
   <virtualdrive1>
      <maxsize>700</maxsize>
      <validfrom>YYYY-mm-dd hh:mm:ss.999</validfrom>
      <validto>YYYY-mm-dd hh:mm:ss.999</validto>
      <devs>
          <dev1>example</dev1>
          <dev2>example</dev2>
      </devs>
      <share>
     <shareuser>user</shareuser>
     <sharepw>sharepw</sharepw>
     <sharepath>sharepath</sharepath>
      </share>
   </virtualdrive1>
</config>
das auslesen der nodes wie validto, validfrom, maxsize usw ist kein problem allerdings habe ich ein problem bie den devs!
Ich muss praktisch abfragen, wieviele devs gibt es und wie sind die Werte...

habe es schon mit:

Delphi-Quellcode:
devs := config.DocumentElement.ChildNodes.First.ChildNodes.FindNode('devs').Text;
aber irgendwie komm ich nicht klar...
hat jemand einen tipp bzw. ein beispiel für mich?

DANKE!

LG

value is NULL 14. Sep 2010 15:17

AW: Xml
 
keiner ne idee :( ?

generic 14. Sep 2010 15:31

AW: Xml
 
Neben den Try / Except gibt es auch Try / Finally.

Delphi-Quellcode:
// Speicher holen
a:=TEinObjekt.Create;
try

  try
    tuWasMitException();
  except
    hierAufraeumenWennFehler();
  end;

 
finally
  // Speicher aber immer! freigeben
  a.free;
end;
btw. zum Abfragen von XML biete sich auch XPath an.

Kalakmul 14. Sep 2010 16:32

AW: Xml
 
Hallo,

mit dem Befehl "Count" kannst Du die Anzahl der Unterknoten ermitteln:

Delphi-Quellcode:
Anzahl := SubNode.ChildNodes.Count;
Dann kannst Du mittels Schleife die einzelnen Einträge auslesen:

Delphi-Quellcode:
for Nr := 1 to Anzahl do
begin
  Eintrag[Nr] := VarToStr(SubNode.ChildValues['Dev' + IntToStr(Nr)]));
end;

samso 14. Sep 2010 17:47

AW: Xml
 
Delphi-Quellcode:
program Test1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  ActiveX,
  XMLIntf,
  XMLDoc;

var
  i: Integer;
  myConfig: IXMLDocument;
  myNode: IXMLNode;
  myNodeList: IXMLNodeList;

begin
  try
    CoInitialize(nil);
    myConfig := LoadXmlDocument('Config.xml');
    myNode := myConfig.DocumentElement.ChildNodes.First.ChildNodes.FindNode('devs');
    if myNode<>nil
    then begin
      myNodeList := myNode.ChildNodes;
      for i := 0 to myNodeList.Count - 1 do
        WriteLn(myNodeList[i].NodeName, ': ', myNodeList[i].NodeValue);
    end;
    ReadLn;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

value is NULL 15. Sep 2010 15:51

AW: Xml
 
Hi leutz

also ich bin meinem Ziel schon ziemlich nahe, ich kann mir jetzt nahezu ALLES auslesen, bis auf eins:

Code:
<virtualdrive id="1">
       NODES
       NODES
       NODES
       NODES
</virtualdrive>
jetzt kann ich aber mehrere blöcke haben wie zB:

Code:
<virtualdrive id="1">
       NODES
       NODES
       NODES
       NODES
</virtualdrive>  
<virtualdrive id="2">
       NODES
       NODES
       NODES
       NODES
</virtualdrive>
dh. ich muss praktisch wieder eine zähler schleife machen und die ID abfragen
? wie würde das in ungefähr funktionieren?

himitsu 15. Sep 2010 16:10

AW: Xml
 
Schau dir doch mal XPath an.

http://de.wikipedia.org/wiki/XPath
http://www.w3.org/TR/xpath/
http://www.w3schools.com/xpath/default.asp
...
Bei Google suchenXPath

value is NULL 21. Sep 2010 15:59

AW: Xml
 
Hi wieder mal :)

ich habe mir ein test.xml angelegt mit folgendem Inhalt:

Code:
<test id="1">
    <wert>100</wert>
    <wert2>500</wert2>
</test>
<test id="2">
    <wert>800</wert>
    <wert2>1200</wert2>
</test>
mein Code sieht wie folgt aus:

Delphi-Quellcode:
program test;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  xmldoc,
  xmlintf,
  activex;

var
  i: Integer;
  myConfig: IXMLDocument;
  myNode: IXMLNode;

begin
    CoInitialize(nil);
    myConfig := LoadXmlDocument('C:\test.xml');
    myNode := myConfig.DocumentElement.ChildNodes.First;
    if (myNode <> nil) then begin
      while (myNode <> nil) do begin
        if (myNode.HasAttribute('id')) then
          Writeln('ID: '+myNode.Attributes['id']);
          mynode := mynode.NextSibling;
        end;
    end;
end.
Damit bekomme ich schön folgendes Ergebnis:
Code:
ID: 1
ID: 2
Das ist für mich ja schon ein großer Schritt :) aaaabbbeeeerrr
Wie ist es möglich, den "wert2" von "testid 1" zu bekommen bzw. von "testid2" ?

irgendwelche Ideen?

danke schon mal

LG

himitsu 21. Sep 2010 16:12

AW: Xml
 
Zitat:

ich habe mir ein test.xml angelegt mit folgendem Inhalt:
Ein XML-Dokument darf nur einen Hauptnoten haben, du hast aber zwei
Delphi-Quellcode:
<test ...>
.
Wenn deine Datei also wirklich genau so aussieht, dann sollte MSXML dieses eigentlich sofort bemängeln.

myNode enthält deine Knoten und da du von diesen die Unterknoten willst, würde ich mit mal
Delphi-Quellcode:
myNode.ChildNodes
ansehn.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:02 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 by Thomas Breitkreuz