Einzelnen Beitrag anzeigen

michele_tedesco

Registriert seit: 19. Mär 2014
50 Beiträge
 
#1

Free von XML-Komponente führt zu EInvalidPointer exception

  Alt 31. Mär 2014, 11:45
Hallo

Ich habe aus einem Form:
Delphi-Quellcode:
unit ViewXML;

interfaces
...

  TfrmXML = class(TForm)
...

var
  frmXML: TfrmXML;

implementation
....

procedure TfrmXML.Button2Click(Sender: TObject);
var
  XMLData: TXMLData;
begin
  if odXMLFile.Execute then
    frmXML.Caption := odXMLFile.FileName;
  try
    XMLData := TXMLData.Create;
    XMLData.XMLToTree(tvXML, odXMLFile.FileName);
  finally
    XMLData.Free;
  end;
end;
...
eine Komponente instantiiert und erhalte eine EInvalidPointer beim Free des Objekts.
Hier die Komponente:
Delphi-Quellcode:
unit ServiceXMLData;

interface
....

  TXMLData = class
  private
    FList: TList<string>;
    FDOC: IXMLDocument;
    FRootNode: IXMLNode;
    Procedure TreeToXML(const Tree: TTreeView);
    procedure IterateXMLNodes(xn: IXMLNode; ParentNode: TTreeNode; var Tree: TTreeView);
    procedure IterateTreeNodes(N: TTreeNode; var ParentXN: IXMLNode);
  public
    Constructor Create;
    Destructor Destroy; override;
    procedure Config;
    Procedure SaveToFile(const fn: String; const Tree: TTreeView);
    procedure XMLToTree(var Tree: TTreeView; const FileName: String);
  end;

implementation
uses
  System.Classes;

{ TXMLData }

procedure TXMLData.Config;
begin
//
end;

constructor TXMLData.Create;
begin
//
  FList := TList<string>.Create;
end;

destructor TXMLData.Destroy;
begin
  FList.Free;
  inherited;
end;


procedure TXMLData.IterateXMLNodes(xn: IXMLNode; ParentNode: TTreeNode; var Tree: TTreeView);
var
  i, j: Integer;
  ChildTreeNode, ChildAttributeTreeNode, ChildTextTreeNode: TTreeNode;
  XMLAttribute: TXMLAttribute;
begin
  For i := 0 to xn.ChildNodes.Count - 1 do
  begin
    if xn.ChildNodes[i].NodeType = TNodeType.ntElement then
    begin
      try
        { XML Node }
        ChildTreeNode := Tree.Items.AddChild(ParentNode, xn.ChildNodes[i].NodeName);
        { XML Node attributes }
        for j := 0 to xn.ChildNodes[i].AttributeNodes.Count -1 do
        begin
          { XML Node attribute key }
          ChildAttributeTreeNode := Tree.Items.AddChild(ChildTreeNode, xn.ChildNodes[i].AttributeNodes[j].NodeName);
          XMLAttribute := TXMLAttribute.create(CXMLAtribute);
          ChildAttributeTreeNode.Data := Pointer(XMLAttribute);
          { XML Node attribute value }
          ChildAttributeTreeNode := Tree.Items.AddChild(ChildAttributeTreeNode, xn.ChildNodes[i].AttributeNodes[j].NodeValue);
          XMLAttribute := TXMLAttribute.create(CXMLAtributeValue);
          ChildAttributeTreeNode.Data := Pointer(XMLAttribute);
        end;
      finally
        XMLAttribute.Free;
      end;
      { recursive call }
      IterateXMLNodes(xn.ChildNodes[i], ChildTreeNode, tree);
    end
    else if xn.ChildNodes[i].NodeType = TNodeType.ntText then
    begin
      try
        { XML Node value }
        ChildTextTreeNode := Tree.Items.AddChild(ParentNode, xn.ChildNodes[i].NodeValue);
        XMLAttribute := TXMLAttribute.create(CXMLText);
        ChildTextTreeNode.Data := Pointer(XMLAttribute);
      finally
        XMLAttribute.Free;
      end;
    end;
  end;
end;

procedure TXMLData.SaveToFile(const fn: String; const Tree: TTreeView);
begin
  FDOC := TXMLDocument.Create(nil);
  FDOC.Options := FDOC.Options + [doNodeAutoIndent];
  FDOC.Active := true;
  TreeToXML(tree);
  FDOC.SaveToFile(fn);
end;

procedure TXMLData.TreeToXML(const Tree: TTreeView);
var
  n: TTreeNode;
begin
  { Root node }
  FRootNode := FDOC.CreateElement('DSXMLExport', '');
  FDOC.DocumentElement := FRootNode;

  { iterate Tree }
  N := Tree.Items[0];
  while Assigned(N) do
  begin
    IterateTreeNodes(N, FRootNode);
    N := N.getNextSibling;
  end;
end;

procedure TXMLData.IterateTreeNodes(N: TTreeNode; var ParentXN: IXMLNode);
var
  CurrXMLNode: IXMLNode;
  Child: TTreeNode;
  s, t: string;
begin
  Child := N.getFirstChild;
  while Assigned(Child) do
  begin
    if Assigned(Child.Data) then
    begin
      { XML node value }
      s := Child.Text;
      try
        if TXMLAttribute(Child.Data).AttributeKey = CXMLText then
        begin
          ParentXN.Text := Child.Text
        end
        { XML node attribute }
        else if TXMLAttribute(Child.Data).AttributeKey = CXMLAtribute then
        begin
          ParentXN.Attributes[Child.Text] := Child.getFirstChild.Text;
        end;
      except
      on E : Exception do
        begin
          MessageDlg('Data of ' + s + ' could could not be read. Exception: '+ E.Message, mtInformation, [mbOK], 0);
        end;
      end;
    end
    else
    begin
      CurrXMLNode := ParentXN.AddChild(N.Text);
      //FDOC.SaveToXML(t);
      IterateTreeNodes(Child, CurrXMLNode);
    end;
    Child := Child.getNextSibling;
  end;
end;

procedure TXMLData.XMLToTree(var Tree: TTreeView; const FileName: String);
var
  Doc: IXMLDocument;
begin
  Doc := NewXMLDocument;
  Doc.LoadFromFile(FileName);
  Doc.Active;
  IterateXMLNodes(Doc.DocumentElement, nil, Tree);
end;

{ TXMLAttribute }

constructor TXMLAttribute.create(AttributeKey: string);
begin
  FAttributeKey := AttributeKey;
end;

function TXMLAttribute.GetAttributeKey: string;
begin
  result := FAttributeKey
end;

procedure TXMLAttribute.SetAttributeKey(s: string);
begin
  FAttributeKey := s;
end;

end.
UPDATE: Im Anhang die PAS-Datei für die XML Komponente
Angehängte Dateien
Dateityp: pas ServiceXMLData.pas (5,5 KB, 2x aufgerufen)

Geändert von michele_tedesco (31. Mär 2014 um 13:31 Uhr) Grund: PAS Datei hinzugefügt
  Mit Zitat antworten Zitat