0

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);
8
  • There is no Xml in parameters of procedure xmlWriteProyectoNode. So - where does it take it from ? and what is the value of XML at the start of procedure. Add the 1st line of procedure xmlWriteProyectoNode as ShowMessage(IntToStr(Integer(Pointer(XML)))); Commented Jul 13, 2013 at 22:23
  • Also show the code creating TXMLDocument ! this class has a number of traps and how you create it is one of those! BTW, "with an Access Violation Error" is better than nothing, but is less than what Delphi told you. Please copy the exact error message here. Commented Jul 13, 2013 at 22:25
  • root := Xml.xmlFile.DocumentElement; is complex line. And "complex" is the same as "ambiguous". Split it to simpler lines. tempvar := Xml.xmlfile; root := tempvar.DocumentElement; Commented Jul 13, 2013 at 22:27
  • @AriochThe "XML" is a record inside the unit. In XML.xmlFile is the instance of TXMLDocument associated in assignXml(). Commented Jul 13, 2013 at 22:28
  • what is the declaration of newXML there ? what is the data type of the var ? Commented Jul 13, 2013 at 22:31

1 Answer 1

3
   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.

Sign up to request clarification or add additional context in comments.

1 Comment

or you could make newXml type iXMLDocument instead as documentation shows, and other variables too. That is a very traps-rich class, so if you want to use it - you have to read the manuals, really have to.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.