Q&A

  • XML문서를 만드는데 문제가 있어서요..
제가 하려고 하는것은
DBGrid에 있는내용을 XML파일로 만들려고 합니다.
그런데 처음부터 난관에 부딪쳐서요..
여기저기 자료를 찾아보는데 예제가 없어서요..

XML문서를 만드는 함수는 아래와 같습니다..

procedure TMakeXML.MakeXMLDoc(AXMLDoc: TXMLDocument;ARootElName,ACntElName,AFileName:string ; AGrid:TDBGrid);
var
   pBrdList : IXMLElement;
   pRoot : IXMLNode;
   pBrdSche : IXMLNode;
   i, nRecord : integer;
begin
   nRecord := AGrid.DataSource.DataSet.RecordCount;
   AXMLDoc.XML.Clear;
   AXMLDoc.XML.Add('<?xml version="1.0" ?>');
   AXMLDoc.XML.Add('<'+ARootElName+'>'+'</'+ARootElName+'>');

   AXMLDoc.Active := true;

   pRoot := AXMLDoc.ChildNodes.Nodes[0];
   pRoot.SetAttribute('ListCount',IntToStr(nRecord));

   AGrid.DataSource.DataSet.First;
   for i := 0 to nRecord - 1 do
   begin
      with AGrid.DataSource.DataSet do
      begin
         pBrdSche := pRoot.AddChild(ACntElName);
         pBrdSche.SetAttribute('ID',FieldByName('F_BRD_ID').AsString);
         Next;
      end;
   end;

   AXMLDoc.SaveToFile(AFileName);

   AXMLDoc.Active := false;
end;

TXMLDocument컴포넌트를 폼에 올린상태에서 하는 내용입니다.
위의 함수 돌리면
pBrdSche := pRoot.AddChild(ACntElName);
이 부분에서        
'This operation can not be performed with a Node of type ELEMENT'
라는 에러 메지시가 나옵니다..
왜 그런것인지 도무지 이해할수가 없습니다.

그리고 한가지 더 의문은 에러나는 부분을 주석처리하고 돌리면
일단 XML 파일이 생성은 되지만.
   pRoot.SetAttribute('ListCount',IntToStr(nRecord));
이 부분이 문제없이 돌아가지만 정장 Attribute는 문서에 추가가 안되네요.
결과의 XML 파일은 아래와 같습니다.

<?xml version="1.0"?>
<BrdList></BrdList>

그럼 좋은 답변들 부탁드립니다.
1  COMMENTS
  • Profile
    이재욱 2004.08.15 03:37
    코드에 실수가 있었네요.
    procedure TMakeXML.MakeXMLDoc(AXMLDoc:TXMLDocument;
                   ARootElName,ACntElName,AFileName:string;ADataSet:TDataSet);
    var
       pBrdList : IXMLElement;
       pRoot : IXMLNode;
       pBrdSche : IXMLNode;
       pBrdField : IXMLNode;
       i, nRecord : integer;
       slFieldNameList : TStrings;
       strTmp : string;
    begin
       nRecord := ADataSet.RecordCount;
       AXMLDoc.XML.Clear;
       AXMLDoc.XML.Add('<?xml version="1.0" ?>');
       AXMLDoc.XML.Add('<'+ARootElName+'>'+'</'+ARootElName+'>');

       AXMLDoc.Active := true;

       pRoot := AXMLDoc.ChildNodes.Nodes[1];
       pRoot.SetAttribute('ListCount',IntToStr(nRecord));

       with ADataSet do
       begin
          slFieldNameList := TStringList.Create;
          GetFieldNames(slFieldNameList);
          while not Eof do
          begin
             pBrdSche := pRoot.AddChild(ACntElName);
             strTmp := FieldList.Strings[0];
             pBrdSche.SetAttribute('ID',FieldByName(strTmp).AsString);
             for i := 0 to FieldCount-1 do
             begin
                strTmp := slFieldNameList.Strings[i];
                pBrdField := pBrdSche.AddChild(strTmp);
                pBrdField.SetNodeValue(FieldByName(strTmp).AsString);
             end;
             Next;
          end;
       end;

       AXMLDoc.SaveToFile(AFileName);

       AXMLDoc.Active := false;
    end;

    pRoot := AXMLDoc.ChildNodes.Nodes[0];
    이부분에서 첫번째 노드는
    <?xml version="1.0"?> 을 뜻하기때문에
    AddNode함수가 먹혀지지 않습니다.
    그래서
    pRoot := AXMLDoc.ChildNodes.Nodes[1];
    와 같이 수정을 한후 하니깐 잘 되네요..

    그런데 AXMLDoc를 Active 하기전에
       AXMLDoc.XML.Clear;
       AXMLDoc.XML.Add('<?xml version="1.0" ?>');
       AXMLDoc.XML.Add('<'+ARootElName+'>'+'</'+ARootElName+'>');
    이렇게 먼저 노드는 넣어주지 않고 하는 방법은 없나요??