AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein XML Delphi Problem mit dem einlesen einer XML-Datei
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit dem einlesen einer XML-Datei

Ein Thema von Bit Juggler · begonnen am 24. Feb 2004 · letzter Beitrag vom 3. Dez 2004
Antwort Antwort
Bit Juggler
(Gast)

n/a Beiträge
 
#1

Problem mit dem einlesen einer XML-Datei

  Alt 24. Feb 2004, 20:58
Hallo,
ich habe das XML Tutorial von Choktay Gründlich gelesen und konnte alles an seinem Beispiel auch wunderbar nachvollziehen.
Nun habe ich hier aber eine XML-Datei die etwas anderst aufgebaut ist, und egal wie ich es auch drehe und wende bekomme ich diese Datei nicht richtig ausgelsen!
Ich habe zu meinem Problem auch schon hier in der DP gesucht, doch selbst eine Procedure von Matthias Simmack konnte mein Problem nicht lösen (GetThoseNodes)

Delphi-Quellcode:

//xmlDoc := CoDOMDocument40.Create usw. spare ich mir mal hier zu posten!
//Ich lade die xml Datei 100% richtig, denn es wird ja auch was angezeigt
//nur nicht korreckt!
//Ich schreibe das nur um dies als Fehler schon einmal auszuschließen!

procedure TForm1.GetThoseNodes(const xmlParent: IXMLDOMNode;
    tvParent: TTreeNode);
  var
    tn : TTreeNode;
    i : integer;
    s : string;
  begin
    // wenn der XML-Parent "nil" ist, dann raus!
    if(xmlParent = nil) then exit;

    // wenn der XML-Parent ein Element ist, dann
    // den Namen ermitteln, ...
    if(xmlParent.Get_nodeType = NODE_ELEMENT) then
      s := xmlParent.Get_nodeName
    // ... ansonsten den Inhalt
    else
      s := xmlParent.Get_nodeValue;

    // ist der TreeView-Parent "nil", dann neuen
    // Knoten an oberster Ebene einfügen, ...
    if(tvParent = nil) then tn := tv.Items.Add(nil,s)
    // ... ansonsten den Parent benutzen und den
    // neuen Knoten darunter einfügen
      else tn := tv.Items.AddChild(tvParent,s);

    // hat der XML-Parent noch untergeordnete Elemente?
    if(xmlParent.childNodes.length > 0) then
    // Ja, dann in einer Schleife diese Prozedur
    // hier erneut aufrufen, ...
      for i := 0 to xmlParent.childNodes.length - 1 do
    // ... und dabei das jeweilige Element sowie den
    // eben erzeugten TreeView-Knoten als Parents übergeben
        GetThoseNodes(xmlParent.childNodes.item[i],tn);
  end;
Es werden zwar im TreeView neue knoten mit entsprechenden Bezeichnungen erstellt, jedoch sozusagen ohne Inhalt!
Ich hoffe das mir das jemand erklären kann, anscheinend ist das ganze für einen Anfänger wohl noch etwas heavy...

XML-Code:
<?xml version="1.0" encoding="iso-8859-1" ?>
- <LISTE>
- <Ordner name="Favoriten" hidden="0" locked="0">
  <platz serviceID="0008" name="KLASSIK" onair="0085" />
  <platz serviceID="000A" name="HIPHOP" onair="0085" />
  <platz serviceID="000B" name="SOUL" onair="0085" />
  <platz serviceID="002B" name="GROOVE" onair="0085" />
  <platz serviceID="0009" name="MODERN" onair="0085" />
  </Ordner>
- <Ordner name="Musik" hidden="0" locked="0">
  <platz serviceID="0004" name="MTV Classic" onair="013E" />
  <platz serviceID="6FEE" name="MTV HITS" onair="0001" />
  <platz serviceID="6FF8" name="MTV HITS." onair="0001" />
  <platz serviceID="6FF9" name="MTV Base." onair="0001" />
  <platz serviceID="0006" name="MTV 1" onair="013E" />
  <platz serviceID="6FF3" name="MTV 2" onair="0001" />
  </Ordner>
</LISTE>
Gruß Bit
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#2

Re: Problem mit dem einlesen einer XML-Datei

  Alt 24. Feb 2004, 21:46
Ich habe die Prozedur, die im übrigen eh von mir ist , mal 1:1 aus dem Browserfenster übernommen und dazu noch deine XML-Datei. Was soll ich sagen? Keine Probleme. Allerdings habe ich sie erweitert, weil eine Anzeige wie
Code:
[-] LISTE
   [-] Ordner
         platz
         platz
         platz
nicht wirklich aussagekräftig ist. Also, nimm meine Prozedur "GetThoseNodes" und füge zwischen
Delphi-Quellcode:
    else
      s := xmlParent.Get_nodeValue;


// --> hier einfügen <-- //


    // ist der TreeView-Parent "nil", dann neuen
    // Knoten an oberster Ebene einfügen, ...
    if(tvParent = nil) then tn := tv.Items.Add(nil,s)
folgendes ein:
Delphi-Quellcode:
    // Attribute anzeigen
    if(xmlParent.attributes.length > 0) then
    begin
      s := s + ' (';

      for i := 0 to xmlParent.attributes.length - 1 do
        s := s +
          xmlParent.attributes.item[i].Get_nodeName +
          '="' +
          xmlParent.attributes.item[i].Get_nodeValue +
          '" ';

      s := s + ')';
    end;
Voilà. Nun zeigt jeder gefundene Knoten in Klammern noch die Attribute an.

Aber hey: ein Problem hatte ich mit deiner XML-Datei, das will ich nicht verschweigen. Ich habe sie aus dem Browser in ein Notepad-Fenster kopiert und natürlich die drei Striche entfernt. Beim Speichern müssen noch irgendwelche Sonderzeichen drin gewesen sein, denn die Ausgabe sah sehr merkwürdig aus. Des Rätsels Lösung war, dass ich
xmldoc.preserveWhiteSpace := false; benutzen musste, dann war das Problem vom Tisch.

Mehr Sorgen hatte ich nicht, und ich habe den Inhalt deiner Datei im Tree-View gesehen.

Zitat:
Delphi-Quellcode:
//xmlDoc := CoDOMDocument40.Create usw. spare ich mir mal hier zu posten!
//Ich lade die xml Datei 100% richtig, denn es wird ja auch was angezeigt
//nur nicht korreckt!
//Ich schreibe das nur um dies als Fehler schon einmal auszuschließen!
Vielleicht wär´s doch mal ganz gut, wenn du diesen Teil postest.
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#3

Re: Problem mit dem einlesen einer XML-Datei

  Alt 24. Feb 2004, 21:55
Zitat von Bit Juggler:
Es werden zwar im TreeView neue knoten mit entsprechenden Bezeichnungen erstellt, jedoch sozusagen ohne Inhalt!
Oh, da fällt mir ein: Falls du genau das meinst:
Code:
[-] LISTE
    [-] Ordner
           platz
           platz
           platz
Das ist kein Fehler, höchstens der Beweis, dass entweder du das Prinzip von XML noch nicht richtig verstanden hast, bzw. dass Chakotays Tutorial noch nicht fertig ist. Oder beides
Code:
<Ordner name="Favoriten" hidden="0" locked="0">
"name", "hidden" und "locked" sind nämlich Attribute. Wie du schon an der gepatchten Funktion in meinem letzten Posting sehen kannst, musst du auf Attribute gesondert zugreifen, sonst siehst du natürlich nur die Knotennamen und ggf. den Inhalt.
  Mit Zitat antworten Zitat
Bit Juggler
(Gast)

n/a Beiträge
 
#4

Re: Problem mit dem einlesen einer XML-Datei

  Alt 24. Feb 2004, 22:05
Hi Matthias,
als erstes einmal:

Zitat von Bit Juggler:
Hallo...
Ich habe zu meinem Problem auch schon hier in der DP gesucht, doch selbst eine Procedure von Matthias Simmack konnte mein Problem nicht lösen (GetThoseNodes)...
Ich schmücke mich nie mit Fremden Federn

Wegen dem fehlenden Teil Sourcecode:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  ...
begin
  fAppPath:= ExtractFilePath(Application.ExeName);
  xmlDoc := CoDOMDocument40.Create;
  xmlDoc.setProperty('NewParser', true);
  ...
  xmlDoc.load(fAppPath + Servicliste); //Servicliste enthält den Pfad zur .xml !
  ...
end
Auf jeden Fall vielen Dank für Deine schnelle Hilfe!
Ich werde es gleich mal ausprobieren, weiß allerdings nicht ob ich es heute noch schaffe mich hier im Forum dazu noch einmal zu äussern!

Gruß Bit

[Nachtrag:
Unsere Postings haben sich gerade überschnitten!
Das mit den Atributen wusste ich nicht, nun weiss ich bescheid!
Das ist dann wohl eindeutig Chakotays schuld da er darüber in seinem Tutorial nichts erwähnt hat
  Mit Zitat antworten Zitat
Bit Juggler
(Gast)

n/a Beiträge
 
#5

Re: Problem mit dem einlesen einer XML-Datei

  Alt 24. Feb 2004, 22:19
Nochmal ich

Das klappt jetzt wunderbar, vielen Dank!

Ein paar Fragen sind nun allerdings noch offen:

1- Wo finde ich den genauere Infos zum XML Format (Atribute usw. ...)
2- Ist es auch möglich aus den einzelnen Nodes nur bestimmte abschnitte heraus zu parsen ?
Also statt: <platz serviceID="0009" name="MODERN" onair="0085" />
nur "MODERN" ;

Gruß Bit

P.S.
Anmerkung zu 2:
Ich will keine komplettlösung, dadurch wird man schnell lernfaul!
Ich möchte nur wissen ob es da spezielle Funktionen / Prozeduren bei den XML Dateien gibt!
Oder noch besser:
Spezielle richtlinien an die ich mich halten muss vielleicht ?
  Mit Zitat antworten Zitat
MathiasSimmack
(Gast)

n/a Beiträge
 
#6

Re: Problem mit dem einlesen einer XML-Datei

  Alt 25. Feb 2004, 07:24
Zitat von Bit Juggler:
1- Wo finde ich den genauere Infos zum XML Format (Atribute usw. ...)
Na ja, zum Format an sich gibt es eigentlich nicht viel zu sagen. Vielleicht habe ich mich da ein wenig unglücklich ausgedrückt. Der "Witz" bei XML ist ja, dass du prinzipiell alles als Tag benutzen kannst was du möchtest. Ob das nun "LISTE" oder "Ordner" ist, oder die Namen von Bekannten und Verwandten ...
Du musst nur unterscheiden lernen zwischen den herkömmlichen Knoten
Code:
<Knoten>
  <Unterknoten/>
</Knoten>
zwischen Attributen
Code:
<Knoten Attribut="wert"/>
und zwischen Versionsangaben, Parsinginfos usw. Wenn du MS-XML 4 installiert hast, dann wirf mal einen Blick in die mitgelieferte Hilfedatei. Oder, falls du das PSDK besitzt, dann schau dort rein, da findest du das gleiche Kapitel ebenfalls.

Zitat:
2- Ist es auch möglich aus den einzelnen Nodes nur bestimmte abschnitte heraus zu parsen ?
Also statt: <platz serviceID="0009" name="MODERN" onair="0085" />
nur "MODERN" ;
Klar, das geht relativ einfach:
node := xmldoc.selectSingleNode('//platz[@name="MODERN"]'); Wenn du also den Knoten mit einem bestimmten Attribut suchst, dann gibst du einfach das @ vor dem Attributnamen an. Und du siehst ja in meinem Codeauszug, dass du so ein Attribut auch als "normalen Node" ansprechen kannst:
xmlParent.attributes.item[0].Get_nodeName als Beispiel.

Zitat:
Ich will keine komplettlösung, dadurch wird man schnell lernfaul!
Ich möchte nur wissen ob es da spezielle Funktionen / Prozeduren bei den XML Dateien gibt!
Ja, einen Teil davon findest du in Chakotays Tutorial und Programm. Einige andere Beispiele gibt es hier in der Sparte (bspw. auch mal ein "Extrem"). Und die grundlegenden Dinge zu den verwendeten Funktionen findest du in der Hilfedatei von XML. Abgesehen davon wollte/will Chakotay sein Tutorial ohnehin noch erweitern.
  Mit Zitat antworten Zitat
Bit Juggler
(Gast)

n/a Beiträge
 
#7

Re: Problem mit dem einlesen einer XML-Datei

  Alt 26. Feb 2004, 00:19
Hallo,
ich habe mir nun das MSXML 4.0 SDK installiert.
Beim einfachen Setup von MSXML 4.0 wird das SDK nanscheinend nicht mitinstalliert, also vielen Dank für Deinen Hinweis
Da habe ich ja jetzt eine gute Quelle zum Nachlesen

Gruß Bit
  Mit Zitat antworten Zitat
Benutzerbild von semo
semo

Registriert seit: 24. Apr 2004
755 Beiträge
 
Delphi 2010 Professional
 
#8

Re: Problem mit dem einlesen einer XML-Datei

  Alt 3. Dez 2004, 15:35
Code:
<?xml version="1.0" standalone="yes"?>
<datapacket day="26" month="8" year="2004" hour="15" min="06" sec="32" msec="386">
    <metadata>
        <fielddefs>
            <fielddef name="Anrede" datatype="string" fieldsize="4" />
            <fielddef name="Titel" datatype="string" fieldsize="5" />
            <fielddef name="Vorname" datatype="string" fieldsize="255" />
            <fielddef name="Nachname" datatype="string" fieldsize="255" />
            <fielddef name="Positionswunsch" datatype="string" fieldsize="255" />
            <fielddef name="Strasse" datatype="string" fieldsize="255" />
            <fielddef name="PLZ" datatype="string" fieldsize="5" />
            <fielddef name="Ort" datatype="string" fieldsize="255" />
            <fielddef name="Land" datatype="string" fieldsize="255" />          
        </fielddefs>
    </metadata>  
    <recorddata>
        <field name="Anrede" value="ghj"/>
        <field name="Titel" value="ghjgj."/>
        <field name="Vorname" value="gjghjg"/>
        <field name="Nachname" value="hjghj"/>
        <field name="Positionswunsch" value="ghjgj-ghj(m/w) - Norddeutghjgjschland"/>
        <field name="Strasse" value="ghj"/>
        <field name="PLZ" value="187876190" />
        <field name="Ort" value="Gghjghjtz" />
        <field name="Land" value="Deutschland" />
    </recorddata>  
</datapacket>

wie parse ich dieses recorddata?
node.Get_nodeName --> gibt immer "field" aus
node.xml --> gibt den xml code des aktuellen Knotens aus
node.Get_text --> ist ja immer leer

wie komme ich an die "name" und "value" felder?
Über Get_NodeValue?

ich habe gesehen dass im tutorial Get_NodeValue einen String zurückliefert.
bei mir ist der rückgabewert aber vom typ oleVariant?!

hab ich da was übersehen?


hier mal mein code:
Code:
var
  node: IXMLDOMNode;
  nodes: IXMLDOMNodeList;
  sOle: OleVariant;
  s: String;
// Parsen des XML-Dokumentes
begin
  xmlDoc := CoDOMDocument30.Create;
  //xmlDoc.setProperty('NewParser', true);  --> nur für 4.0 Version!
  xmlDoc.validateOnParse   := False;
  xmlDoc.resolveExternals  := False;
  xmlDoc.async             := False;
  xmlDoc.preserveWhiteSpace := False;

  if not xmlDoc.load(sDateiname) then
    MessageDlg('XML-Datei nicht vorhanden!', mtWarning, [mbOK], 0);


  // Durchlaufen einer NodeList: -----------------------------------------------
  nodes := xmlDoc.selectNodes('//recorddata[0]/*');
  node := xmlDoc.selectSingleNode('//recorddata[0]/*');

  for i := 0 to nodes.length-1 do
  begin

    if (node <> nil) then
    begin
      node := nodes.nextNode;

      // einlesen des nodeValues, dabei ist das Ergebnis vom Typ OleVariant
      sOle := node.Get_nodeValue;

      case varType(sOle) of
        varStrArg:      ShowMessage('COM-compatible string');
        varEmpty  :    ShowMessage('The variant is Unassigned');
        varOleStr  :   ShowMessage('Reference to a dynamically allo...');
        varVariant  :  ShowMessage('A variant');
        varString  :   ShowMessage('Reference to a dynamically ...');
        varNull  :     ShowMessage('The variant is Null.');
        varSmallint  : ShowMessage('16-bit signed integer (type Sm....');
        varInteger :    ShowMessage('32-bit signed integer (type Integ...).');
        varSingle :     ShowMessage('Single-precision floating-point valu....');
        varDouble  :   ShowMessage('Double-precision floating-point value (type double).');
        varCurrency  : ShowMessage('Currency floating-point value (type Currency).');
        varDate  :     ShowMessage('Date and time value (type TDateTime).');
        varDispatch  : ShowMessage('Reference to an Automation object (an IDi....');
        varError :      ShowMessage('Operating system error code.');
        varBoolean :    ShowMessage('16-bit boolean (type WordBool).');
        varUnknown :    ShowMessage('Reference to an unknown object (an IInterface or IUnknown interface pointer).');
        varByte  :     ShowMessage('A Byte');
        varAny :        ShowMessage('A CORBA Any value.');
      end;

      {
      // wir wollen jetzt das Ergebnis vom Typ OleVariant
      // in einen String umwandeln
      iResult := VariantChangeType( sOle,
                                    sOle,
                                    0,
                                    VT_BSTR);

      // das Ergebnis der Umwandlung prüfen
      case iResult of
        S_OK: ShowMessage('Success.');
        DISP_E_BADVARTYPE: ShowMessage('The variant type vtNew ....');
        DISP_E_OVERFLOW:ShowMessage('The data pointed to by p.....');
        DISP_E_TYPEMISMATCH:   ShowMessage('The argument could not ....');
        E_INVALIDARG:   ShowMessage('One of the arguments is invalid.');
        E_OUTOFMEMORY:   ShowMessage('Memory could not be allocated for the conversion.');
      end;

      // wenn Ergebnis ok ist weiterverfahren ansonsten abbrechen
      if iResult <> S_OK then
        exit;
      }

      s := '';
      //s := VarAsType(sOle, varString);

      // If VariantChangeType did not return an error,
      // the argument could then be fetched directly from the bstrVal field of the VARIANTARG
      //s:= sOle.bstrval;


      MessageDlg( 'lfd. Nr.:        ' + #9 + IntToStr(i)       + #13#10 +
                  'Nodename:        ' + #9 + node.Get_nodeName + #13#10 + 
                  'NodeInhalt:      ' + #9 + node.xml          + #13#10 + 
                  'Get_NodeValue:   ' + #9 + s                 + #13#10 + 
                  'NodeGetText:     ' + #9 + node.Get_text,              
                  mtInformation, [mbOK], 0);
    end;

  end;
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz