【问题标题】:how to create xml file in delphi如何在delphi中创建xml文件
【发布时间】:2011-12-02 10:06:01
【问题描述】:

我是 delphi 新手,现在我必须阅读创建 xml。我的代码如下:

单元写入xml1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, xmldom, XMLIntf, StdCtrls, msxmldom, XMLDoc;

type
  TForm1 = class(TForm)
    XMLDocument1: TXMLDocument;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SaveClick(Sender: TObject);
var
  rootName: String;
  childNode: String;
  attrChild: string;
  iXml: IDOMDocument;
  iRoot, iNode, iNode2, iChild, iAttribute: IDOMNode;
  XMLDoc: TXMLDocument;
begin
  XMLDoc.Active := False;
  XMLDoc.XML.Text := '';
  XMLDoc.Active := True;
  XMLDoc.SaveToFile('C:\Documents and Settings\a\Desktop\zulfa.xml');
  iXml := XMLDoc.DOMDocument;
  iRoot := iXml.appendChild(iXml.createElement('xml'));
  iNode := iRoot.appendChild(iXml.createElement('test'));
  iNode.appendChild(iXml.createElement('test2'));
  iChild := iNode.appendChild(iXml.createElement('test3'));
  iChild.appendChild(iXml.createElement('Simple calue'));
  iNode.insertBefore(iXml.createElement('test4'), iChild);
  iNode2 := iNode.cloneNode(True);
  iRoot.appendChild(iNode2);
  iAttribute := iXml.createAttribute('color');
  iAttribute.nodeValue := 'red';
  iNode2.attributes.setNamedItem(iAttribute);
end;

end.

问题是点击保存按钮时显示异常,异常是

Project writexml1.exe raised exception class EAccessViolation  with message 
'Access violation at address 004391B9 in module writexml.exe

【问题讨论】:

  • 与您的问题无关,但是为什么要在包含任何 XML 之前将 XMLDoc 的内容保存到文件中?看起来您的代码永远不会生成包含 xml 的文件。

标签: delphi delphi-7


【解决方案1】:

您的代码看起来有点复杂。我建议:忘记TXMLDocumentIDOMDOCUMENT,改用IXMLDOCUMENT(使用它的方式与TXmlDocument 几乎相同,但你不需要组件)。

这段代码应该演示一下,它是多么简单:

{...}
Var
  XML : IXMLDOCUMENT;
  RootNode, CurNode : IXMLNODE;
begin
  XML := NewXMLDocument;
  XML.Encoding := 'utf-8';
  XML.Options := [doNodeAutoIndent]; // looks better in Editor ;)
  RootNode := XML.AddChild('XML');
  CurNode := RootNode.AddChild('Test');
  CurNode := CurNode.AddChild('Test2');
  CurNode.Text := 'Some Test 2 text';
  CurNode.Attributes['NewAttribute'] := 'Some Test2 Attribute Value';
  XMl.SaveToFile('C:\Documents and Settings\a\Desktop\zulfa.xml');
{...}

生成的文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<XML>
  <Test>
    <Test2 NewAttribute="Some Test2 Attribute Value">Some Test 2 text</Test2>
  </Test>
</XML>

希望对你有帮助

PS:此示例只需要 Units XMLIntfXmlDoc,因此您可以稍微整理一下 uses

【讨论】:

    【解决方案2】:

    您需要先创建XMLDoc 实例才能使用它:

    XMLDoc := TXMLDocument.Create(...);
    try
      ... do stuff with XMLDOC
    finally
      XMLDoc.Free;
    end;
    

    【讨论】:

    • 不过要小心。使用nil 所有者动态创建TXMLDocument 会导致TXMLDocument 充当接口而不是对象。在这样的实例上调用Free() 会非常糟糕。如果你想使用Free(),那么你必须提供一个非nil的所有者(在这种情况下,Free()是多余的,因为当所有者被释放时,所有者将释放TXMLDocument)。如果您使用nil 所有者动态分配TXMLDocument,则必须将其分配给IXMLDocument 变量,在这种情况下使用NewXMLDocument() 而不是TXMLDocument.Create(nil)
    • @remy 我编辑答案以放入构造函数中。但我不知道要传递什么参数。因此......原来的答案缺乏细节。
    • 像任何其他组件一样,TXMLDocument 的构造函数将TComponent 所有者作为输入。如果您指定非nil 所有者,则所有者将拥有释放TXMLDocument 的所有权。如果您改为指定 nil 所有者,则 TXMLDocument 将是无所有者的,您有责任释放它。但是TXMLDocument 在后一种情况下是特殊的,因为当它具有nil 所有者时,它不会充当普通组件,而是充当引用计数接口,因此您必须涉及引用计数系统才能按顺序正确释放它。
    • @Remy:当我通过NewXmlDocument()分配XML文档时,当不再需要实例时如何释放它?
    • @truthseeker: NewXmlDocument() 返回一个引用计数的IXMLDocument 接口。当不再引用它时,它会自动释放。你可以让它正常超出范围,也可以分配nil给它,如果你想提前释放它。
    【解决方案3】:

    SaveClick() 正在声明一个本地 XMLDoc 变量,该变量在您使用 i 之前未分配有效的 TXMLDocument 对象。您的TForm 上有一个单独的XMLDocument1 组件,但您没有使用它。摆脱XMLDoc 并改用XMLDocument1

    此外,您正在直接访问底层DOMDocument。请改用TXMLDocument 自己的方法来构建 XML,除非您需要访问特定于供应商的功能(在这种情况下不需要),否则不要下拉到 DOM 层。

    试试这个:

    procedure TForm1.SaveClick(Sender: TObject); 
    var 
      iRoot, iNode, iNode2, iChild: IXMLNode; 
    begin 
      XMLDocument1.Active := False;
      XMLDocument1.XML.Text := '';    
      XMLDocument1.Active := True;
      iRoot := XMLDocument.AddChild('xml'); 
      iNode := iRoot.AddChild('test'); 
      iNode.AddChild('test2'); 
      iChild := iNode.AddChild('test3'); 
      iChild.Text := 'Simple value'; 
      iNode.AddChild('test4', iNode.ChildNodes.IndexOf(iChild)); 
      iNode2 := iNode.CloneNode(True); 
      iRoot.ChildNodes.Add(iNode2); 
      iNode2.Attributes['color'] := 'red'; 
      XMLDocument1.SaveToFile('C:\Documents and Settings\a\Desktop\zulfa.xml'); 
      XMLDocument1.Active := False;
    end; 
    

    生成以下 XML:

    <?xml version="1.0" encoding="utf-8"?>
    <xml>
      <test>
        <test2 />     
        <test4 />
        <test3>Simple value</test3>
      </test>
      <test color="red">
        <test2 />     
        <test4 />
        <test3>Simple value</test3>
      </test>
    </xml>
    

    话虽如此,像@knowledgestacker 建议的那样,使用IXMLDocument 而不是TXMLDocument 通常是更好的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-14
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多