Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Delphi Von MSXML zu OmniXML kleines Problem aufgetreten (https://www.delphipraxis.net/22525-von-msxml-zu-omnixml-kleines-problem-aufgetreten.html)

Tillmet 18. Mai 2004 20:11


Von MSXML zu OmniXML kleines Problem aufgetreten
 
Hi
Also, ich rätsle hier schon sehr lange dran, doch wie ich euch kenne, findet ihr eine schnelle und einfache Lösung, auf die ich einfach mal wieder nicht gekommen bin :?: . Also, mein Problem ist, ich habe mit MS XML was gemacht, doch nun stellte sich herraus, dass auf dem Einsatzpc kein MS XML vorhanden ist und nicht installiert werden kann. Gut, dachte ich mir, dann suchste mal. Dabei ist OmniXML herausgekommen, die Lösung schien mir wunderbar, und es klappte wirklich, alle Befehle von MS XML umzuschreiben, war kein Problem, hatte ich hier http://www.delphipraxis.net/internal...hlight=omnixml gefunden und vorher habe ich Chakotay1308s Tutorial zum Thema XML mit MS XML gelesen, hatte das Programm damit ja auch schon fertig gestellt, es liest nur eine XML Datei ein, gibt es in einer Tabelle aus und man kann dann die einzelnen Einträge verändern.
Mein Problem ist nur der eine Schritt, bei dem das einfache umschreiben des Befehles zu einem Fehler führt. Hier mal der Code:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  id: String;
  node: IXMLNode;
begin
  id := Tabelle.Items[Tabelle.ItemIndex].Caption;
  node := XMLDoc.documentElement.selectSingleNode(id);
  node.selectSingleNode('daten') := ComboBox1.Text;
  XMLDoc.save(AppPath + 'database.xml');
  UpdateList;
end;
So, hier kommt an der Stelle
Delphi-Quellcode:
  node.selectSingleNode('daten') := ComboBox1.Text;
Ein Fehler, also tippe ich mal, dass irgendwas daran nicht stimmt, unter MS XML funzt es jedoch, das is das Problem.
Was könnte ich noch machen? Oder hat einer ein ganzes Tut zu OmniXML? Von www.omnixml.com

CalganX 18. Mai 2004 20:40

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Hi,
ein Tutorial kann ich dir nicht liefern, allerdings die Lösung:
Code:
node.selectSingleNode('daten')[color=#ff0000].text[/color] := ComboBox1.Text;
;)

Chris

Tillmet 18. Mai 2004 20:42

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Sorry, muss dich enttäuschen, funzt auch nicht, hatte auch nur vergessen, es oben in den Code zu schreiben, sry.
Wie könnte ich denn mal testen, ob es überhaupt an der Funktion liegt und nicht an der Tabelle, oder der ComboBox?

Edit:
Delphi-Quellcode:
  node.selectSingleNode('daten').text := 'Hallo';
Habe es so gemacht und funzt auch nicht.

CalganX 18. Mai 2004 21:06

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Hi,
prüfe mal, ob node überhaupt existiert (sprich <> nil ist). Ansonsten muss du gucken, ob deine XSL-Abfrage richtig ist.

Chris

MathiasSimmack 18. Mai 2004 21:16

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Zitat:

Zitat von Chakotay1308
Ansonsten muss du gucken, ob deine XSL-Abfrage richtig ist.

XSL? XPath, meinst du wohl? ;)

CalganX 18. Mai 2004 21:18

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Hi,
stimmt das meine ich. :oops:
Nachdem sakura einmal eine Variable sXSL genannt hat und dann damit XPath gemacht hat, komme ich ständig durcheinander. :mrgreen: *alles auf die katze schieb* ;)

Chris

Tillmet 18. Mai 2004 21:20

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Also, um es besser zu sehen, mal der ganze Code:



Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OmniXML, ComCtrls, StdCtrls;

type
  TForm1 = class(TForm)
    Tabelle: TListView;
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    ComboBox1: TComboBox;
    ComboBox2: TComboBox;
    procedure FormCreate(Sender: TObject);
    procedure UpdateList;
    procedure TabelleColumnClick(Sender: TObject; Column: TListColumn);
    procedure TabelleCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  XMLDoc: IXMLDocument;
  AppPath: string;
  ColumnToSort: Integer;
  LastSorted: Integer;
  SortDir: Integer;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  AppPath := ExtractFilePath(Application.ExeName);
  XMLDoc := CreateXMLDoc;
  XMLDoc.DocumentElement := XMLDoc.CreateElement('daten');
  if not FileExists(AppPath+'database.xml') then begin
    XMLDoc.loadXML('<?xml version="1.0" encoding="ISO-8859-1"?><Daten></Daten>');
  end else
    XMLDoc.load(AppPath+'database.xml');
  if XMLDoc.parseError.errorCode <> 0 then begin
    MessageDlg('Die XML Datei ist nicht korrekt!' + #13#10
    + 'Das Programm wird nun beendet!', mtError, [mbOK], 0);
    Application.Terminate;
  end;
  UpdateList;
end;



procedure TForm1.UpdateList;
var
  daten: IXMLNodeList;
  subNode: IXMLNode;
  i: integer;
begin

Tabelle.Items.Clear;
  Tabelle.Items.BeginUpdate;
  daten := XMLDoc.documentElement.selectNodes('daten');
  for i:=0 to daten.length -1 do begin
    subNode := daten.item[i].selectSingleNode('name');
    Tabelle.Items.Add;
    Tabelle.Items[i].Caption := subNode.Text;
    with Tabelle.Items[i].SubItems do begin
        subNode := daten.item[i].selectSingleNode('klasse');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt1');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt2');
        if subNode <> nil then
          Add(subNode.Text);
      end;
    end;
  Tabelle.Items.EndUpdate;
end;



procedure TForm1.TabelleColumnClick(Sender: TObject; Column: TListColumn);
begin
  ColumnToSort := Column.Index;
  if ColumnToSort = LastSorted then
    SortDir := 1 - SortDir
  else
    SortDir := 0;
  LastSorted := ColumnToSort;
  (Sender as TCustomListView).AlphaSort;
end;

procedure TForm1.TabelleCompare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
var
  ix: Integer;
begin
  if ColumnToSort = 0 then
  begin
    if SortDir = 0 then
      Compare := CompareText(Item1.Caption,Item2.Caption)
    else
      Compare := CompareText(Item2.Caption,Item1.Caption);
  end //if ColumnToSort = 0 then
  else
  begin
   ix := ColumnToSort - 1;
   if SortDir = 0 then
     Compare := CompareText(Item1.SubItems[ix],Item2.SubItems[ix])
   else
     Compare := CompareText(Item2.SubItems[ix],Item1.SubItems[ix]);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  id: String;
  node: IXMLNode;
begin
  id := Tabelle.Items[Tabelle.ItemIndex].Caption;
  node := XMLDoc.documentElement.selectSingleNode('prowo/daten'+id);
  if node = nil then showmessage('is da');
  node.selectSingleNode('daten').text := 'Hallo';
  XMLDoc.save(AppPath + 'database.xml');
  UpdateList;
end;

end.

MathiasSimmack 18. Mai 2004 21:43

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
1. Das hier
Zitat:

Delphi-Quellcode:
XMLDoc.DocumentElement := XMLDoc.CreateElement('daten');

ist relativ sinnlos, weil du danach den XML-Code sowieso aus der Datei holst, bzw. im Code erzeugst. ;)

2. Bist du sicher, dass dein Dokument so aufgebaut ist
Code:
<Daten>
  <prowo>
    <daten1>
      <!--
         1 als Beispiel, weil ich nicht weiß, was
         "id := Tabelle.Items[Tabelle.ItemIndex].Caption;"
         für eine ID zurückgibt
      -->
    </daten1>
  </prowo>
</Daten>
Zumindest sucht deine XPath-Anweisung nach diesem Knoten
Zitat:

Delphi-Quellcode:
node := XMLDoc.documentElement.selectSingleNode('prowo/daten'+id);

3. Das hier ist albern:
Zitat:

Delphi-Quellcode:
if node = nil then showmessage('is da');

Anders herum wird ein Schuh draus. Wenn "node" ungleich nil ist, dann ist der Knoten da. ;)

4. Ist nicht gesagt, dass der Knoten "daten" dann auch existiert
Zitat:

Delphi-Quellcode:
node.selectSingleNode('daten').text := 'Hallo';

Zur Sicherheit solltest du so vorgehen:
Delphi-Quellcode:
subnode := node.selectSingleNode('daten');

// Knoten existiert
if(subnode <> nil) then
  subnode.text := 'Hallo'
else
// Knoten existiert nicht, also: anlegen
begin
  subnode := XMLDoc.createElement('daten');
  if(subnode <> nil) then
  begin
    subnode.text := 'Hallo';
    node.appendChild(subnode);
  end;
end;
(Angabe ohne Gewähr, weil ich an MS-XML gedacht habe.)

Tillmet 18. Mai 2004 21:57

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
:cry: nix will klappen.
Mit MS XML geht es, genau wie du sagts, aber mit Omni will es einfach nicht, ich teste noch weiter, wenn ich was finde, sage ich es.

Edit: Also, ich würde ja gerne mit MSXML arbeiten, aber wie kann ich das auf eineml PC ohne MSXML nutzen?

MathiasSimmack 19. Mai 2004 07:39

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Zitat:

Zitat von Tillmet
Edit: Also, ich würde ja gerne mit MSXML arbeiten, aber wie kann ich das auf eineml PC ohne MSXML nutzen?

Gar nicht. Aber du könntest mal deinen bisherigen Quellcode hier anhängen, evtl. mit einer Beispiel-XML-Datei, damit man auch weiß, wie das Ding aufgebaut ist, was ausgelesen werden soll, usw. Dann könnte man sich das mal selbst anschauen.

Tillmet 19. Mai 2004 18:06

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe mal das Ganze angehängt, wenn du OmniXML hast, kannste es gerne nachtesten.

MathiasSimmack 20. Mai 2004 14:20

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Ich denke, dass es nicht an dir oder deinem Programm liegt. Es sieht so aus, als wäre die XPath-Implementation in OmniXML noch nicht vollständig. Sie kann zwar Knoten finden
Code:
/daten/name
und auch Attribute
Code:
/daten/name/@testattribut
aber sie kann anscheinend bisher noch nicht mit Filtern umgehen. Und Filter sind eben genau die Bedingungen, die du in eckigen Klammern angibst
Code:
/daten[name="' + id + '"]
Du solltest dir darum im Moment mit einem Work-Around behelfen. Wenn du also nach dem Namen (sprich: der ersten Spalte der List-View) suchst, dann würde das bspw. so aussehen:
Delphi-Quellcode:
  node   := nil;
  daten  := XMLDoc.DocumentElement.SelectNodes('daten/name');
  for i  := 0 to daten.Length - 1 do
    if({Tabelle.Selected.Caption =} id = daten.Item[i].Text) then
    begin
      node := daten.Item[i].GetParentNode;
      break;
    end;

  if(node <> nil) then
  begin
    ShowMessage(node.XML);
  end;

Tillmet 20. Mai 2004 22:14

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Gut, dein Work Around zeigt die Daten schonmal gut an, ein Schritt weiter also, aber wie soll ich denn dann bearbeiten, etc?
Habe von OmniXML echt keine Peilung, sry.

Edit: okok, Du bist ein Gott und ich ein Idiot, sry. Musste jetzt ja nur noch
Delphi-Quellcode:
  node.selectSingleNode('projekt1').text := ComboBox1.Text;
machen, dann hatte ich ja die selectierte Node, vielen Dank, dann mache ich jetzt mal weiter, bis der nächste Punkt bei Omni kommt, den ich nicht kann ^^, vielen Dank.


Edit2: Ich hoffe, du liest das hier ^^. Also, wenn ich schon dabei bin zu fragen, dann mache ich gleich mal weiter. Wie könnte ich denn jetzt noch eine Suchfunktion einbauen? Ein Edit Feld, in das gibt man Klasse, oder Name ein und es wird dann gesucht? Geht das bei ListView? Wenn ja, wie? Oder haste gleich mal ein ListView Tutorial zur Hand?

MathiasSimmack 21. Mai 2004 07:16

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Zitat:

Zitat von Tillmet
Edit: okok, Du bist ein Gott [...]

Ich weiß. *fingernägelanhauchundamShirtabwisch*

Zitat:

[...] und ich ein Idiot, sry.
Ich w... *g* Ich meine, das kann ich nicht beurteilen. ;)

Zitat:

Wie könnte ich denn jetzt noch eine Suchfunktion einbauen? Ein Edit Feld, in das gibt man Klasse, oder Name ein und es wird dann gesucht? Geht das bei ListView?
Ja, das müsstest du aber IMHO selbst programmieren. Die Subitems lassen sich relativ einfach durchsuchen, da es sich ja um eine Stringliste handelt, die "IndexOf" kennt (s. Hilfe). Aber du müsstest meiner Meinung nach in einer Schleife durch die Einträge der List-View durch und dann eben schauen ob du was findest. Du solltest evtl. berücksichtigen, dass es identische Einträge gibt. (Gut, das weiß ich nicht, aber möglich ist IMHO ja alles ... :stupid:) In dem Fall wäre es vielleicht ganz gut, eine Art Auswahl zu gestatten, indem du die identischen Einträge noch mal auflistest. Vergleichbar mit dem Index von Hilfedateien.

Tillmet 21. Mai 2004 10:45

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Hi
Danke nochmal, klappt soweit alles, nur mein Ansatz für das Durchsuchen scheitert immer. Ich habe mir gedacht, ich verbinde einfach deinen Vorschlag für das Suchen der einzelnen Datensätze und den alten Code, von der Theorie klappt es auch, und praktisch auch zu ca. 50% :wink: Doch, 2 Probleme bleiben offen, guck es dir an:

Delphi-Quellcode:
procedure TForm1.Edit1Change(Sender: TObject);
var
  daten: IXMLNodeList;
  i,j: integer;
  subNode: IXMLNode;
  node: IXMLNode;
begin
  j := 0;
  Tabelle.Items.Clear;
  Tabelle.Items.BeginUpdate;
  daten := XMLDoc.documentElement.selectNodes('daten/name');
  for i:=0 to daten.length -1 do begin
  if(Edit1.Text = daten.Item[i].Text) then
    begin
    subNode := daten.item[i].ParentNode('name');
    Tabelle.Items.Add;
    Tabelle.Items[j].Caption := subNode.Text;
    with Tabelle.Items[j].SubItems do begin
        subNode := daten.item[i].selectSingleNode('klasse');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt1');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt2');
        if subNode <> nil then
          Add(subNode.Text);
        j := j+1;
      end;
    end;
      break;
    end;

  Tabelle.Items.EndUpdate;
end;
Das Problem ist, wenn ich bei
Delphi-Quellcode:
    Tabelle.Items[j].Caption := subNode.Text;
Jetzt := 'Hallo' machen würde, würde es gehen, doch so geht's leider nicht, denn in der subNode wird nichts aufgenommen, da ich am Anfang ja leider
Delphi-Quellcode:
  daten := XMLDoc.documentElement.selectNodes('daten/name');
machen muss, sonst würde es bis dahin wieder nicht funktionieren. Doch er findet jetzt ja keine Node mit Namen, da die schon geladen is, oder irgendwie was in der Richtung, das ist auf jeden Fall Fehler 1, den ich gerade versuche zu beheben.
Fehler 2 wäre dann, dass ich gerne hätte, dass man auch nur "Na" in das Edit Feld eingeben kann und dann schon alle Daten, die "Na" drin haben angezeigt werden, und je mehr man vom Namen eingibt, desto mehr beschränkt sich die Auswahl.
Ach und eine kleine Frage am Rande, was heißt IMHO???

Edit:
Ok, das eine hätte ich ja behoben, wenn ich statt
Delphi-Quellcode:
subNode := daten.item[i].ParentNode('name');
Delphi-Quellcode:
    subNode := daten.item[i];
machen würde, aber dann besteht das Prob ja weiterhin, da ich dann nicht auf Klasse etc. zugreifen kann, da ich schon zu tief in den Nodes drin bin.


Edit2:
Ok, nächsten Fehler behoben:
Delphi-Quellcode:
procedure TForm1.Edit1Change(Sender: TObject);
var
  daten, daten2: IXMLNodeList;
  i, mu: integer;
  subNode: IXMLNode;
begin
  Tabelle.Items.Clear;
  Tabelle.Items.BeginUpdate;
  daten := XMLDoc.documentElement.selectNodes('daten');
  for i:=0 to daten.Length do begin
  mu := Pos (Edit1.Text, daten.Item[i].Text);
  if(mu <> 0) then
    begin
    daten2 := XMLDoc.DocumentElement.SelectNodes('daten');
    subNode := daten.item[i].SelectSingleNode('name');
    Tabelle.Items.Add;
    Tabelle.Items[i].Caption := subNode.Text;
    with Tabelle.Items[i].SubItems do begin
        subNode := daten.item[i].SelectSingleNode('klasse');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt1');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt2');
        if subNode <> nil then
          Add(subNode.Text);
      end;
    end;
      break;
    end;

  Tabelle.Items.EndUpdate;
end;
Frag mich nicht wie, aber es geht soweit. Das Problem ist nun folgendes, es wird immer höchstens nur ein Datensatz angezeigt, also muss irgendwas an der Schleife falsch sein.

MathiasSimmack 21. Mai 2004 11:45

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Ich verstehe wohl heute nur die Hälfte (oder noch weniger) von dem was du schreibst. Du erzählst was von einer Suche in der List-View. Warum greifst du dann aber auf die XML-Datei zu? Ich meine, sämtliche Angaben stehen doch schon in der LV. :?
Du brauchst doch also nur eine Schleife, die durch alle Items in der LV durchgeht und dort nach dem gewünschten Begriff sucht - sowohl in der "Caption" als auch in den SubItems. Bei letzteren kannst du "IndexOf" benutzen.

Und hier
Delphi-Quellcode:
        if subNode <> nil then
          Add(subNode.Text);
solltest du auch berücksichtigen, dass ein Knoten mal leer sein kann, bzw. gar nicht gefunden wird. Das hast du zwar durch die Prüfung auf nil, aber wenn der Knoten eben mal nil ist, dann werden keine SubItems in die LV eingefügt.
Wenn du dann irgendwo im Code versuchst, auf das x. SubItem zuzugreifen, wäre ein unschöner Fehler die Folge. Mach´s also besser so:
Delphi-Quellcode:
        if subNode <> nil then
          Add(subNode.Text)
        else
          Add('');
Zitat:

Ach und eine kleine Frage am Rande, was heißt IMHO???
Was hast du denn für einen Browser? Bei mir wird der Begriff grün unterstrichelt, und wenn man die Maus drauf hält, dann bekommt man die Erklärung. ;)

Tillmet 21. Mai 2004 11:56

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Okok, hast wie immer völlig Recht, wozu denn XML ^^, ich kanns doch einfach in der ListView Ordnen lassen, nur weiß ich noch nicht genau, wie ich die Schleife machen soll, doch das mache ich jetzt mal.
Ach und zu meinem Browser, ich habe IE 6.0, aber dank meinem XP Style funzt das mit dem grünen leider nicht, früher hats das mal ^^.

Edit:
Also, könntest du mir sagen, was es heißt ^^?
Und könntest du mich noch ein Stück näher an meine Antwort mit der Schleife heranführen?

Edit2:
Um es nochmal ganz genau zu sagen, Ich habe jetzt die XML Datei in der ListView, ok. Man kann es auch durch Klicken auf die Columns auf und absteigend ordnen, und auch das Verändern, des Projektes, durch die ComboBox funzt wunderbar. Jetzt würde ich aber gerne noch, damit man nicht immer so viel scrollen muss, ein Edit Feld einbauen, und wenn man dort z.B. was eingibt, wie "Til" sollte die ListView sich bei jedem eingegebenen Buchstaben (halt OnChange) verändern, und zwar sollte sie dann nur die Namen anzeigen, die mit "Til" anfangen, oder es beinhalten, damit ich dann da einfacher das Projekt verändern kann. Und da habe ich keine Peilung wie, denn ich habe noch nie mit ListView, und XML gearbeitet, und sowieso bin ich nicht so ein toller Coder...sry

Tillmet 22. Mai 2004 12:56

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Also, ich schließe das mal als erledigt ab, denn mein XML Problem ist ja gelöst, der Rest hat jetzt mit anderen Komponenten zu tun, und nochmals vielen Dank.

Ich habe es übrigens so hinbekommen, wie ich es ca. wollte, ich muss nur noch an der Suchfunktion pfeilen, damit er auch nach Teilen in dem String sucht, und nicht nur, wenn man das ganze Wort eingegeben hat.
Hier mal der neue Code, is eigentlich ganz einfach gewesen, wirste sehen:

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OmniXML, ComCtrls, StdCtrls, StrUtils, Menus;

type
  TForm1 = class(TForm)
    Tabelle: TListView;
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    Button2: TButton;
    ComboBox1: TComboBox;
    ComboBox2: TComboBox;
    MainMenu1: TMainMenu;
    Datei1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure UpdateList;
    procedure TabelleColumnClick(Sender: TObject; Column: TListColumn);
    procedure TabelleCompare(Sender: TObject; Item1, Item2: TListItem;
      Data: Integer; var Compare: Integer);
    procedure Button1Click(Sender: TObject);
    procedure Edit1Change(Sender: TObject);
    procedure Edit2Change(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  XMLDoc: IXMLDocument;
  AppPath: string;
  ColumnToSort: Integer;
  LastSorted: Integer;
  SortDir: Integer;
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  AppPath := ExtractFilePath(Application.ExeName);
  XMLDoc := CreateXMLDoc;
  XMLDoc.DocumentElement := XMLDoc.CreateElement('daten');
  if not FileExists(AppPath+'database.xml') then begin
    XMLDoc.loadXML('<?xml version="1.0" encoding="ISO-8859-1"?><Daten></Daten>');
  end else
    XMLDoc.load(AppPath+'database.xml');
  if XMLDoc.parseError.errorCode <> 0 then begin
    MessageDlg('Die XML Datei ist nicht korrekt!' + #13#10
    + 'Das Programm wird nun beendet!', mtError, [mbOK], 0);
    Application.Terminate;
  end;
  UpdateList;
end;



procedure TForm1.UpdateList;
var
  daten: IXMLNodeList;
  subNode: IXMLNode;
  i: integer;
begin

Tabelle.Items.Clear;
  Tabelle.Items.BeginUpdate;
  daten := XMLDoc.documentElement.selectNodes('daten');
  for i:=0 to daten.length -1 do begin
    subNode := daten.item[i].selectSingleNode('name');
    Tabelle.Items.Add;
    Tabelle.Items[i].Caption := subNode.Text;
    with Tabelle.Items[i].SubItems do begin
        subNode := daten.item[i].selectSingleNode('klasse');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt1');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt2');
        if subNode <> nil then
          Add(subNode.Text);
      end;
    end;
  Tabelle.Items.EndUpdate;
end;



procedure TForm1.TabelleColumnClick(Sender: TObject; Column: TListColumn);
begin
  ColumnToSort := Column.Index;
  if ColumnToSort = LastSorted then
    SortDir := 1 - SortDir
  else
    SortDir := 0;
  LastSorted := ColumnToSort;
  (Sender as TCustomListView).AlphaSort;
end;

procedure TForm1.TabelleCompare(Sender: TObject; Item1, Item2: TListItem;
  Data: Integer; var Compare: Integer);
var
  ix: Integer;
begin
  if ColumnToSort = 0 then
  begin
    if SortDir = 0 then
      Compare := CompareText(Item1.Caption,Item2.Caption)
    else
      Compare := CompareText(Item2.Caption,Item1.Caption);
  end //if ColumnToSort = 0 then
  else
  begin
   ix := ColumnToSort - 1;
   if SortDir = 0 then
     Compare := CompareText(Item1.SubItems[ix],Item2.SubItems[ix])
   else
     Compare := CompareText(Item2.SubItems[ix],Item1.SubItems[ix]);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  node: IXMLNode;
  daten: IXMLNodeList;
  i: integer;
begin
  node   := nil;
  daten  := XMLDoc.DocumentElement.SelectNodes('daten/name');
  for i  := 0 to daten.Length - 1 do
    if(Tabelle.Selected.Caption = daten.Item[i].Text) then
    begin
      node := daten.Item[i].GetParentNode;
      break;
    end;

  if(node <> nil) then
  begin
    ShowMessage(node.XML);
    node.selectSingleNode('projekt1').text := ComboBox1.Text;
    UpdateList;
  end;
end;


procedure TForm1.Edit1Change(Sender: TObject);
var
  daten: IXMLNodeList;
  subNode: IXMLNode;
  i, j: integer;
begin
j := 0;
Tabelle.Items.Clear;
  Tabelle.Items.BeginUpdate;
  daten := XMLDoc.documentElement.selectNodes('daten');
  for i:=0 to daten.length -1 do begin
    subNode := daten.item[i].selectSingleNode('name');
    If (SoundEx(subNode.Text,2) = SoundEx(Edit1.Text,2)) then
    begin
    Tabelle.Items.Add;
    Tabelle.Items[j].Caption := subNode.Text;
    with Tabelle.Items[j].SubItems do begin
        subNode := daten.item[i].selectSingleNode('klasse');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt1');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt2');
        if subNode <> nil then
          Add(subNode.Text);
      end;
      j := j+1;
    end;
    end;
  Tabelle.Items.EndUpdate;
end;

procedure TForm1.Edit2Change(Sender: TObject);
var
  daten: IXMLNodeList;
  subNode: IXMLNode;
  i, j: integer;
begin
j := 0;
Tabelle.Items.Clear;
  Tabelle.Items.BeginUpdate;
  daten := XMLDoc.documentElement.selectNodes('daten');
  for i:=0 to daten.length -1 do begin
    subNode := daten.item[i].selectSingleNode('name');
    If (subNode.Text = Edit2.Text) then
    begin
    Tabelle.Items.Add;
    Tabelle.Items[j].Caption := subNode.Text;
    with Tabelle.Items[j].SubItems do begin
        subNode := daten.item[i].selectSingleNode('klasse');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt1');
        if subNode <> nil then
          Add(subNode.Text);
        subNode := daten.item[i].selectSingleNode('projekt2');
        if subNode <> nil then
          Add(subNode.Text);
      end;
      j := j+1;
    end;
    end;
  Tabelle.Items.EndUpdate;

end;

end.
Wie gesagt, einfach nur noch eine If Abfrage dazwischen, bei OnChange, jetzt wird es wunderbar angezeigt.

Edit:
So, alles geht soweit, habe auch die Suchfunktion mit einer netten Funktion, die ich hier im Forum gefunden habe verbessert, alles wunderbar soweit, jetzt muss ich noch das Speichern einbauen, damit man das dann auch als txt oder doc, oder sonstwas hat.

aps 18. Jul 2004 09:37

Re: Von MSXML zu OmniXML kleines Problem aufgetreten
 
Zitat:

Zitat von Tillmet
Delphi-Quellcode:
    XMLDoc.loadXML('<?xml version="1.0" encoding="ISO-8859-1"?><Daten></Daten>');

Frage: Funktioniert das bei dir? Mit MS-XML klappte das auch bei mir, aber OmniXML wirft immer eine Exception "ungültiges Zeichen im Tag" aus. Ich nehme an, wegen des ? als erstes Zeichen im Tag.


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