使用 IXML 个节点创建 XML 个文档

Creating XML document with IXMLNodes

喂!我想将 IXMLNodes 添加到 XML 文档。我的主要程序是 btnXmlSaveToFileClick,它将 XML 结构保存到文件中。我的问题是我无法将 IXMLNode 添加为 child。对不起我的英语。

如有任何帮助或建议,我们将不胜感激。

这是我的例子:

*

unit Unit3;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  XMLDoc, XMLIntf, Vcl.StdCtrls;

type
  IXMLDataSample1 = interface(IXMLNode)
  ['{D7B7E084-1BF8-4185-85D1-1C83B74EA651}']
    function GetXmlDAtaSample1: WideString;
    procedure SetXmlDAtaSample1(const Value: WideString);
    property XmlDataSample1: WideString read GetXmlDataSample1 write SetXmlDataSample1;
  end;

  IXMLDataSample2 = interface(IXMLNode)
  ['{6D7CE38B-3F57-4F18-A337-8405E72637E6}']
    function GetXmlDataSample2: WideString;
    procedure SetXmlDataSample2(const Value: WideString);
    property XmlDataSample2: WideString read GetXmlDataSample2 write SetXmlDataSample2;
  end;

  TXMLHandler<IXMLType: IXMLNode> = class
  private
    class function ConvertXMLNodeToXMLType(aNode: IXMLNode): IXMLType;
  protected
    class function GetXMLClass: TClass; virtual; abstract;
    class function GetXMLRootElementName: WideString; virtual; abstract;
    class function GetXMLIfType: TGUID; virtual; abstract;
    class procedure SaveXMLToFile(aXML: IXMLType; const aFileName: string);
    class function NewXML: IXMLType; virtual;
  end;

  TDataSampleXMLHandler1 = class(TXMLHandler<IXMLDataSample1>)
  public
    class function GetXMLClass: TClass; override;
    class function GetXMLRootElementName: WideString; override;
    class function GetXMLIfType: TGUID; override;
  end;

  TDataSampleXMLHandler12 = class(TXMLHandler<IXMLDataSample2>)
  protected
    class function GetXMLClass: TClass; override;
    class function GetXMLRootElementName: WideString; override;
    class function GetXMLIfType: TGUID; override;
  end;

  TForm3 = class(TForm)
    btnXmlSaveToFile: TButton;
    procedure btnXmlSaveToFileClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

type
  TXMLSampleDataObj1 = class(TXMLNode, IXMLDataSample1)
  private
    function GetXmlDataSample1: WideString;
    procedure SetXmlDataSample1(const Value: WideString);
  end;

  TXMLSampleDataObj2 = class(TXMLNode, IXMLDataSample2)
  private
    function GetXMlDataSample2: WideString;
    procedure SetXmlDAtaSample2(const Value: WideString);
  end;

procedure TForm3.btnXmlSaveToFileClick(Sender: TObject);
 //Works well
  vXML1 := TDataSampleXMLHandler1.NewXML;
  vXML1.XmlDataSample1 := 'test data';
  TDataSampleXMLHandler1.SaveXMLToFile(vXml1, 'C:\Teszt\XmlSample.XML');

  //My problem here, cannot add IXMLNode to XMLDocument
  vXMLDoc := NewXMLDocument;
  vXMLDoc.ChildNodes.Add(vXML1);
  //And add vXML2 and more...
  vXMLDoc.SaveToFile('C:\Teszt\XmlDocSaveSAmple.XML');
end;

{ TXMLHandler<IXMLType> }

class function TXMLHandler<IXMLType>.ConvertXMLNodeToXMLType(
  aNode: IXMLNode): IXMLType;
begin
  Result := default(IXMLType);
  try
    Supports(aNode, GetXMLIfType, result);
  finally
    aNode := nil;
  end;
end;

class function TXMLHandler<IXMLType>.NewXML: IXMLType;
begin
  Result :=
      ConvertXMLNodeToXMLType(NewXMLDocument.GetDocBinding(GetXMLRootElementName, GetXMLClass, ''));
end;

class procedure TXMLHandler<IXMLType>.SaveXMLToFile(aXML: IXMLType;
  const aFileName: string);
begin
  aXML.OwnerDocument.SaveToFile(aFileName);
end;

{ TDataSampleXMLHandler12 }


class function TDataSampleXMLHandler12.GetXMLClass: TClass;
begin
  Result := TXMLSampleDataObj2;
end;

class function TDataSampleXMLHandler12.GetXMLIfType: TGUID;
begin
  Result := IXMLDataSample2;
end;

class function TDataSampleXMLHandler12.GetXMLRootElementName: WideString;
begin
  Result := 'Sample2'
end;

{ TDataSampleXMLHandler1 }

class function TDataSampleXMLHandler1.GetXMLClass: TClass;
begin
  Result := TXMLSampleDataObj1;
end;

class function TDataSampleXMLHandler1.GetXMLIfType: TGUID;
begin
  Result := IXMLDataSample1;
end;

class function TDataSampleXMLHandler1.GetXMLRootElementName: WideString;
begin
  Result := 'Sample2';
end;

{ TXMLSampleDataObj1 }

function TXMLSampleDataObj1.GetXmlDataSample1: WideString;
begin
  Result := ChildNodes['XmlDataSample1'].Text;
end;

procedure TXMLSampleDataObj1.SetXmlDataSample1(const Value: WideString);
begin
  ChildNodes['XmlDataSample1'].NodeValue := Value;
end;

{ TXMLSampleDataObj2 }

function TXMLSampleDataObj2.GetXMLDataSample2: WideString;
begin
  Result := ChildNodes['XmlDataSample2'].Text;
end;

procedure TXMLSampleDataObj2.SetXmlDataSample2(const Value: WideString);
begin
  ChildNodes['XmlDataSample2'].NodeValue := Value;
end;

end.*

将单个 XML 节点保存到文档中效果很好。但是我想将这些节点添加到应用程序停止的 XML 文档中,没有错误。 我的问题是:

 procedure TForm3.btnXmlSaveToFileClick(Sender: TObject);
 //Works well
  vXML1 := TDataSampleXMLHandler1.NewXML;
  vXML1.XmlDataSample1 := 'test data';
  TDataSampleXMLHandler1.SaveXMLToFile(vXml1, 'C:\Teszt\XmlSample.XML');

  //My problem here, cannot add IXMLNode to XMLDocument
  vXMLDoc := NewXMLDocument;
  vXMLDoc.ChildNodes.Add(vXML1);
  //And add vXML2 and more...
  vXMLDoc.SaveToFile('C:\Teszt\XmlDocSaveSAmple.XML');
end;

我终于 XML 我想要的样子:

<?xml version="1.0"?>
<Sample2>
   <XmlDataSample2>test data</XmlDataSample2>
</Sample2>
<Sample1>
   <XmlDataSample1>test data</XmlDataSample1>
</Sample1>

XML 标准只允许文档中有 1 个 顶级 元素。您将不得不使 <Sample... > 元素成为另一个顶级元素的子元素,例如:

<?xml version="1.0"?>
<Samples>
  <Sample2>
    <XmlDataSample2>test data</XmlDataSample2>
  </Sample2>
  <Sample1>
    <XmlDataSample1>test data</XmlDataSample1>
  </Sample1>
</Samples>
procedure TForm3.btnXmlSaveToFileClick(Sender: TObject);
var
  vXMLDoc: IXMLDocument;
  vXML1: IXMLDataSample1;
  vXMLSamples: IXMLNode;
begin
  vXML1 := TDataSampleXMLHandler1.NewXML;
  vXML1.XmlDataSample1 := 'test data';

  vXMLDoc := NewXMLDocument;
  vXMLSamples := vXMLDoc.AddChild('Samples');
  vXMLSamples.ChildNodes.Add(vXML1);
  //And add vXML2 and more...
  vXMLDoc.SaveToFile('C:\Teszt\XmlDocSaveSample.XML');
end;