Question

Im try develop a helper to read/write and control an instance of TXMLDocument. I write a simple unit for this work. The unit have a procedure that assign the instance to global variable, and set some variables for document control. The unit is:

unit Globals;

{ Variables globales de la aplicacion, con sus correspondientes accessors }

interface

uses
  { XML Helper }
  xmldom, XMLIntf, msxmldom, XMLDoc, SysUtils, DateUtils;

type
  XmlCheckPoint = Record
    asociado: boolean;
    xmlFile: TXMLDocument;
    saved: boolean;
    lastModification: TDateTime;
    lastSave: TDateTime;
    path: TFilename;
  End;

  { Firmas }
  procedure assignXml(var aXml: TXMLDocument);
  procedure xmlWriteProyectoNode(obra,cliente,ubicacion,fecha,sondeo,estudio: String);
  function existsXml(): boolean;
  function xmlIsUpdated(): boolean;

var
  Xml: XmlCheckPoint;

The procedure assignXml, works fine:

  procedure assignXml(var aXml: TXMLDocument);
  begin
    Xml.xmlFile := aXml;
    Xml.asociado := true;
    Xml.saved := false;
    Xml.lastSave := Yesterday;
    Xml.path := '';
    { Inserto el nodo raiz }
    Xml.xmlFile.Active := true;
    Xml.xmlFile.AddChild('raiz');
    Xml.lastModification := Now();
  end;

But, xmlWriteProyectoNode(...) explodes the app:

procedure xmlWriteProyectoNode(obra,cliente,ubicacion,fecha,sondeo,estudio: String);
  var
    root,meta,child: IXMLNode;
  begin
    Xml.xmlFile.Active := true;
    root := Xml.xmlFile.DocumentElement;
    meta := root.AddChild('proyecto');
    child := meta.AddChild('obra');
    child.Text := obra;
      [...]
    Xml.lastModification := Now();
  end;

The app crash when invoques writeXmlProyectoNode(...) with an Access Violation Error. In execution time. The Embarcadero debuger says that the conflicting line is:

root := Xml.xmlFile.DocumentElement;

I need get the root element, and was think this was the correct way... Im newest in Delphi, any ideas ?. Thanks !.

Edit: The XML Creation ( newXml type is TXMLDocument )

newXml := TXMLDocument.Create(nil);
newXml.Options := [doNodeAutoIndent];
newXml.Active := true;
{ Asocio la instancia de XMLDocument a mi variable global newXml}
Globals.assignXml(newXml);
Was it helpful?

Solution

   var newXml: TXMLDocument; // instead of "iXMLDocument"
   newXml := TXMLDocument.Create(nil);

And now please read the documentation about creating the document with or without the owner.

You should either create it as plain object, that lives until you .Free it - but then it should have an owner.

Or you should use reference-counted interfaces and ALWAYS keep at least one variable alive that links to the document.

The latter approach shown in... again in the documentaton:

Read the documentation

PS.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top