Нарушение прав доступа при попытке получить узел XML
Я пытаюсь разработать помощник для чтения / записи и управления экземпляром TXMLDocument. Я пишу простой блок для этой работы. В модуле есть процедура, которая назначает экземпляр глобальной переменной и устанавливает некоторые переменные для управления документами. Единица является:
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;
Процедура assignXml, отлично работает:
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;
Но xmlWriteProyectoNode(...) взрывает приложение:
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;
Сбой приложения при вызове writeXmlProyectoNode(...) с ошибкой нарушения прав доступа. Во время исполнения. Отладчик Embarcadero говорит, что конфликтующая строка:
root := Xml.xmlFile.DocumentElement;
Мне нужно получить корневой элемент, и я думаю, что это был правильный путь... Я новичок в Delphi, есть идеи? Спасибо!.
Изменить: создание XML (newXml
тип TXMLDocument
)
newXml := TXMLDocument.Create(nil);
newXml.Options := [doNodeAutoIndent];
newXml.Active := true;
{ Asocio la instancia de XMLDocument a mi variable global newXml}
Globals.assignXml(newXml);
1 ответ
var newXml: TXMLDocument; // instead of "iXMLDocument"
newXml := TXMLDocument.Create(nil);
А теперь, пожалуйста, прочитайте документацию о создании документа с владельцем или без него.
- http://docwiki.embarcadero.com/Libraries/XE4/en/Xml.XMLDoc.TXMLDocument
- http://docwiki.embarcadero.com/Libraries/XE4/en/Xml.XMLDoc.TXMLDocument.Create
Вы должны либо создать его как простой объект, который живет до вас .Free
это - но тогда это должно иметь владельца.
Или вы должны использовать интерфейсы с подсчетом ссылок, и ВСЕГДА сохраняйте хотя бы одну переменную, которая ссылается на документ.
- http://en.wikipedia.org/wiki/Reference_counting
- http://docwiki.embarcadero.com/RADStudio/XE4/en/Implementing_IInterface
Последний подход показан в... снова в документе:
- http://docwiki.embarcadero.com/CodeSamples/en/TXMLDocument_use_case_(Delphi)
- http://docwiki.embarcadero.com/Libraries/XE4/en/Xml.XMLIntf.IXMLDocument
Читать документацию
- http://docwiki.embarcadero.com/Libraries/XE2/en/System.IUnknown
- http://docwiki.embarcadero.com/RADStudio/XE4/en/Object_Interfaces
- http://docwiki.embarcadero.com/RADStudio/XE4/en/Interface_References
PS.