1
votes

I try to merge two XML files (created with MSword) with the code bellow but although it runs without any error, i receive an error message when i try to open the merged file. Actually the merged file contains the first's file content plus only the first line of the second (the line " < ?xml version="1.0" encoding="UTF-8" standalone="yes" ? > "). No merged contents!

// button select the first file then button2 selects the second and merges them

uses XML.xmlDoc,XML.XMLintf;

var XMLDoc1, XMLDoc2 : TXMLDocument;

procedure TForm30.Button1Click(Sender: TObject);
begin
    if OpenDialog1.Execute then begin
        XMLDoc1 := TXMLDocument.Create(self);
        XMLDoc1.Active := True;
        XMLDoc1.LoadFromFile(OpenDialog1.filename);
    end;
end;

procedure TForm30.Button2Click(Sender: TObject);
var ANode: IXMLNode;
begin
    if OpenDialog1.Execute then begin
        XMLDoc2 := TXMLDocument.Create(self);
        xmlDoc2.Active:= True;
        XMLDoc2.LoadFromFile(OpenDialog1.filename);
        ANode:= XMLDoc2.ChildNodes[0].CloneNode(True);
        xmlDoc1.ChildNodes.add(ANode);
        xmlDoc2.Active:= False;
        xmlDoc1.SaveToFile('c:\' + 'Merge.xml');
        XMLDoc1.free;
        XMLDoc2.free;
        aNode.free;
    end;
end;

What i'm doing wrong, please ? thanks in advance.

1
XML can only have 1 top-level document element, but your code is trying to create 2 top-level elements. Also, you are not taking into account that XMLDoc2.ChildNodes[0] may not be the top-level document element, it could be other node types. In this case, it sounds it is the prolog node. You should use the XMLDoc2.DocumentElement property instead.Remy Lebeau
thanks Remy, you are right. But I don't know how can I force the two docs to be merged. Any help will be invaluable.JimPapas

1 Answers

3
votes

XML can only have 1 top-level document element, but your code is trying to create 2 top-level elements.

Also, you are not taking into account that XMLDoc2.ChildNodes[0] may not be the top-level document element. It can be other node types, like processing instructions, etc. In this case, it sounds it is the XML prolog node. To access the top-level element node, use the XMLDoc2.DocumentElement property instead.

If you need to add the second document's top-level element as a child of the first document's top-level element, then try something more like this:

uses
  Xml.XmlDoc, Xml.XmlIntf;

var
  XMLDoc1, XMLDoc2 : IXMLDocument;

procedure TForm30.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then begin
    XMLDoc1 := LoadXMLDocument(OpenDialog1.FileName);
  end;
end;

procedure TForm30.Button2Click(Sender: TObject);
var
  ANode: IXMLNode;
begin
  if OpenDialog1.Execute then begin
    XMLDoc2 := LoadXMLDocument(OpenDialog1.FileName);
    ANode := XMLDoc2.DocumentElement.CloneNode(True);
    XMLDoc1.DocumentElement.ChildNodes.Add(ANode);
    XMLDoc1.SaveToFile('C:\Merge.xml');
    XMLDoc1 := nil;
    XMLDoc2 := nil;
  end;
end;

On the other hand, if you need to preserve both documents' top-level elements, you will have to create a new document with its own top-level element and then add the two documents as its children:

uses
  Xml.XmlDoc, Xml.XmlIntf;

var
  XMLDoc1, XMLDoc2 : IXMLDocument;

procedure TForm30.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then begin
    XMLDoc1 := LoadXMLDocument(OpenDialog1.FileName);
  end;
end;

procedure TForm30.Button2Click(Sender: TObject);
var
  ANode: IXMLNode;
  XMLDoc3: IXMLDocument;
begin
  if OpenDialog1.Execute then begin
    XMLDoc2 := LoadXMLDocument(OpenDialog1.FileName);
    XMLDoc3 := NewXMLDocument;
    ANode := XMLDoc3.AddChild('merged');
    ANode.ChildNodes.Add(XMLDoc1.DocumentElement.CloneNode(True));
    ANode.ChildNodes.Add(XMLDoc2.DocumentElement.CloneNode(True));
    XMLDoc3.SaveToFile('C:\Merge.xml');
    XMLDoc1 := nil;
    XMLDoc2 := nil;
  end;
end;