2016-09-28 5 views
0

일부 값을 변경 한 후에 XML 파일을 저장하는 데 문제가 있습니다. 내가 여기 FPC 버전 3.0.0 와 IDE로 나사로 1.6을 사용 나는이 게시물에 대한 사용 내 XML 파일의 구조입니다 : 사용 나는 다음을 사용나사로와 함께 TFilestream을 하드 드라이브에 저장하는 방법

<?xml version="1.0" encoding="UTF-8"?> 
<wbpickeys> 
    <picture> 
    <name>C:\IMG_1.JPG</name> 
    <imagedate>p-06/04/2014 16:22:10</imagedate> 
    <favorit>n</favorit> 
    <remark>aaa</remark> 
    <drive>DRIVE_FIXED</drive> 
    </picture> 
</wbpickeys> 

절은 (그들 모두하지 될 수있다 필요하지만) 중요한 한 번 사용할 수있는 적어도 생각 : TFileStream을) : 프로그램 시작에

uses 
Windows, ShellAPI, FileUtil, Graphics, Menus, ComCtrls, ExtCtrls, ExtDlgs, Classes, SysUtils, LResources, Forms, Controls, StdCtrls, Dialogs, CheckLst, Buttons, inifiles, 
laz2_DOM, laz2_XMLRead, laz2_XMLWrite, laz2_XMLCfg, laz2_XMLUtils, laz_XMLStreaming; 

가 나는 TFileStream을 (g_stream으로이 XML 파일을로드합니다. 그 이유는 프로그램이 실행되는 동안 독점적 인 액세스 권한을 갖는 것입니다. 내가 한 childNode에의 텍스트 값을 변경보다

function open_xml:Boolean; 
begin 
    if g_stream <> nil then FreeAndNil(g_stream); 
    try 
      //with load from (TFile)-Stream the xml file can be opened with Share Exclusive 
      //when loading only from file there is no possibility to open it exclusive 
      g_stream:= TFileStream.Create('wbpickeys.xml',fmShareExclusive); 
      //Read the XML file into an XML Document 
     readxmlfile(g_wbpickeys,g_stream); 
      result:= true; 
    except 
     on E:EFOpenError do 
     begin 
      beep(); 
       MessageDlg 
     (
      //br is defined as a constance for line feed 
     '*** A T T E N T I O N ***' + br + br + 
      'When trying to open the file for the keywords' + br + '"wbpickeys.xml"' + br + 
      'the following error occurs:' + br + 
      E.Message + br + 
      'Please check if the file is available' + br + 
      'or deleted or moved or what else',mtError,[mbOK],0 
     ); 
     result:= false; 
     end; 
    end; 
end; 

: 내가 다음 open 함수를 사용하여이를 달성하기 위해

procedure TForm1.BChangeNodeClick(Sender: TObject); 
var 
    pictures   : TDOMNodeList; 
    pic, tempnode  : TDOMNode; 
    i     : integer; 
begin 
    // Get all nodes with name "picture" 
    pictures:= g_wbpickeys.GetElementsByTagName('picture'); 
    // For all Member nodes 
    for i:= 0 to pictures.Count - 1 do 
    begin 
    pic:= pictures[i]; 
    tempnode:= pic.FindNode('remark'); 
    // if content is 'bbb' change it 
    if(tempnode.TextContent = 'bbb') then 
    begin 
     tempnode.TextContent:= 'aaa'; 
     //than I try to save the xmldocument to the hard drive  
     writeXMLFile(g_wbpickeys,'wbpickeys.xml'); 
    end; 
end; 

그리고 여기 내 문제 : 새로운 텍스트를 설정하고 나는한다 결과를 메모로 볼 수 있습니다. 하지만이 값은 런타임 중에 XML이로드되는 메모리에서만 변경되었지만 하드 드라이브의 파일에는 물리적으로 변경되지 않았습니다. 거의 모든 부분을 훑어 보았지만 스트림을 하드 드라이브의 해당 파일에 저장하는 솔루션을 찾을 수 없었습니다.

나는이 "writeXMLFile (g_wbpickeys, 'wbpickeys.xml');"를 사용하는 경우 내가 파일 lazutf8classes.pas 라인 (143)

문제에서 "파일 wbpickeys.xml을 생성 할 수 없습니다"라는 EFCreateError를 얻을 수를 XML 파일을 만들고 싶지 않습니다. 기존 파일을 변경하고 싶습니다.

이상 나는 스트림을 디스크의 파일에 저장할 가능성을 찾았습니다. Bur 불행히도 나는 그것에 대해 아무것도 찾지 못했습니다.

확실히 실수입니다 만 볼 수는 없습니다. 누군가 내게 알려 줄 수 있니?

+0

다른 파일 스트림을 만들고 해당 스트림에 복사하십시오. –

답변

1

수정 된 문서를 다시 디스크에 기록 할 때 전체 파일을 바꾸어야하므로 수정 된 노드로만 작업을 제한 할 수 없습니다. 따라서 먼저 오래된 XML 파일을 삭제해야합니다 (또는 더 잘 작성하십시오 : 쓰기 도중 문제가 발생하는 경우를 대비하여 이름 바꾸기). 그런 다음 WriteXMLFile을 사용하여 문서를 작성하십시오. 또는 항상 원래 파일을 잠근 상태로 유지하기 위해 새 임시 파일 이름을 쓸 수 있습니다. 독서 스트림을 파괴 (독점 액세스를 끝내기 위해), 원래 파일을 삭제하고 새 파일의 이름을 이전 파일로 바꿉니다.

+0

와우 - 정말 복잡한 것 같습니다. Bevor 저는 델파이를 사용했고 훨씬 더 쉬웠습니다. 그러나 그 대답에 대해 많은 감사드립니다. –

+0

복잡한가? 나는 이것을 단순화하는 방법을 상상할 수 없다. 그리고 델파이가 어떻게 다르게 할 수 있었는지 상상할 수 없습니다. –

+0

나는 진정한 전문가는 아니지만, 델파이와 writeXML 함수로 xml을 생성하지는 않지만이 함수는 기존 파일을 변경한다고 생각합니다. 함수가 backround에서 같은 일을했을 수도 있습니다. 기존의 것을 삭제하고 새 것을 작성하십시오. 그러나 이것보다는 사용자가 그것에 대해 생각하게하지 않고 작동합니다. 어쨌든 - 귀하의 제안을 따랐습니다. 너무 감사합니다. Andreas –