Hallo Wolfgang,
was hast du vor? Möchtest du die Knoten der TreeView direkt editieren und dann die Änderungen per RefreshXML in das
XML-Dokument übernehmen? Das ist keine gute Idee, finde ich. Die TreeView sollte dir lediglich Zugang zum
XML-Dokument verschaffen, deine Änderungen sollten dort eingetragen werden und danach sollte die TreeView - als rein visuelle Komponente - aktualisiert werden.
Es gibt bei der Gestaltung von
XML-Dokumenten ein uraltes Problem, über dass sich jeder irgendwann Gedanken machen muss: soll eine Information als Attributwert oder als Elementinhalt gespeichert werden. Diese Entscheidung sollte nie leichtfertig getroffen werden, da sie Auswirkungen auf die Überlebensfähigkeit des Codes hat. Im von dir verwendeten
XML-Dokument scheinen mir nur Attribute zu existieren, die du ohne Unterscheidung zu Elementen in die TreeView einbaust.
Du versuchst den Pfadnamen deines Knoten zur Verwendung in FindNode() aufzubauen. Der dabei verwendete Backslash ist im Filesystem angebracht, in XPath-Ausdrücken wird ein Slash verwendet. Dabei gehst du in deiner WHILE-Schleife davon aus, dass ab Level 2 ein Attribut-Knoten vorliegt. Attribut-Knoten können aber in deinem
XML-Dokument auf verschiedenen Ebenen auftreten.
In deiner TreeView trägst du aus diesen Gründen nur die Attribute der Elemente ein, die keine Unterelemente mehr besitzen. Diese Einschränkung wirst du sicher nicht durchhalten, aber im Augenblick solltest du dann auch das Editieren nur auf Blattknoten zulassen.
Ich habe deinen Code nur minimal überarbeitet, damit der von dir beschriebene Fehler verschwindet. Ich hoffe du siehst die Änderungen.
Delphi-Quellcode:
// ...
var
de: IDOMElement;
// ...
// Parents sammeln und in einer StringList speichern
if ATreeNode.Parent <>
nil
then begin
HelpTreeNode := ATreeNode.Parent;
repeat
AStringList.Insert(0,HelpTreeNode.Parent.Text);
HelpTreeNode := HelpTreeNode.Parent;
until HelpTreeNode.Level = 0;
// NodeName zusammenstellen
ANodeName :='
';
for i := 0
to Pred(AStringList.Count)
do
begin
ANodeName := ANodeName + AStringList.Strings[i];
if i <> Pred(AStringList.Count)
then ANodeName := ANodeName + '
/';
end;
// XML-File beschreiben
with AXMLDocument.DocumentElement.DOMNode
as IDOMNodeSelect
do
begin
de := SelectNode(ANodeName)
as IDOMElement;
if Assigned(de)
then
de.setAttribute(ATreeNode.Parent.Text, ATreeNode.Text);
end;
end;
// ...
Freundliche Grüße vom marabu