2012-06-28 115 views
11

我想讀取XML文件的一些節點,並在一些自定義輸入字段中顯示它們的值。用戶可以根據需要更改這些值,並通過單擊Next按鈕將這些值保存回XML。如何讀取和寫入XML文檔節點值?

如何在InnoSetup腳本中做到這一點?

+0

相關問題:[Inno Setup基於自定義輸入修改XML文件](http://stackoverflow.com/q/8141886/588306)。 – Deanna

回答

23

使用CreateOleObject函數實例化標準的MSXML2.DOMDocument COM對象。下面的腳本顯示瞭如何加載和保存文本值用於從下面貼(腳本本身通過從MSDN實施例的啓發)的XML文件中的單個節點:

[Setup] 
AppName=My Program 
AppVersion=1.5 
DefaultDirName={pf}\My Program 
DefaultGroupName=My Program 
UninstallDisplayIcon={app}\MyProg.exe 
Compression=lzma2 
SolidCompression=yes 
OutputDir=userdocs:Inno Setup Examples Output 

[Files] 
Source: "MyProg.exe"; DestDir: "{app}" 
Source: "MyProg.chm"; DestDir: "{app}" 

[Icons] 
Name: "{group}\My Program"; Filename: "{app}\MyProg.exe" 

[Code] 
var 
    CustomEdit: TEdit; 
    CustomPageID: Integer; 

function LoadValueFromXML(const AFileName, APath: string): string; 
var 
    XMLNode: Variant; 
    XMLDocument: Variant; 
begin 
    Result := ''; 
    XMLDocument := CreateOleObject('Msxml2.DOMDocument.6.0'); 
    try 
    XMLDocument.async := False; 
    XMLDocument.load(AFileName); 
    if (XMLDocument.parseError.errorCode <> 0) then 
     MsgBox('The XML file could not be parsed. ' + 
     XMLDocument.parseError.reason, mbError, MB_OK) 
    else 
    begin 
     XMLDocument.setProperty('SelectionLanguage', 'XPath'); 
     XMLNode := XMLDocument.selectSingleNode(APath); 
     Result := XMLNode.text; 
    end; 
    except 
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK); 
    end; 
end; 

procedure SaveValueToXML(const AFileName, APath, AValue: string); 
var 
    XMLNode: Variant; 
    XMLDocument: Variant; 
begin 
    XMLDocument := CreateOleObject('Msxml2.DOMDocument.6.0'); 
    try 
    XMLDocument.async := False; 
    XMLDocument.load(AFileName); 
    if (XMLDocument.parseError.errorCode <> 0) then 
     MsgBox('The XML file could not be parsed. ' + 
     XMLDocument.parseError.reason, mbError, MB_OK) 
    else 
    begin 
     XMLDocument.setProperty('SelectionLanguage', 'XPath'); 
     XMLNode := XMLDocument.selectSingleNode(APath); 
     XMLNode.text := AValue; 
     XMLDocument.save(AFileName); 
    end; 
    except 
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK); 
    end; 
end; 

procedure InitializeWizard; 
var 
    CustomPage: TWizardPage; 
begin 
    CustomPage := CreateCustomPage(wpWelcome, 'Custom Page', 
    'Enter the new value that will be saved into the XML file'); 
    CustomPageID := CustomPage.ID; 
    CustomEdit := TEdit.Create(WizardForm); 
    CustomEdit.Parent := CustomPage.Surface; 
end; 

procedure CurPageChanged(CurPageID: Integer); 
begin 
    if CurPageID = CustomPageID then 
    CustomEdit.Text := LoadValueFromXML('C:\Setup.xml', '//Setup/FirstNode'); 
end; 

function NextButtonClick(CurPageID: Integer): Boolean; 
begin 
    Result := True; 
    if CurPageID = CustomPageID then 
    SaveValueToXML('C:\Setup.xml', '//Setup/FirstNode', CustomEdit.Text); 
end; 

下面是在所使用的XML文件腳本:

<?xml version="1.0" encoding="UTF-8"?> 
<Setup> 
    <FirstNode>First node value!</FirstNode> 
    <SecondNode>Second node value!</SecondNode> 
</Setup> 
+0

P.S.將這個腳本中的每個OLE對象函數調用與['OleCheck'](http://www.jrsoftware.org/ishelp/topic_isxfunc_olecheck.htm)包裝在一起會很好,這會在函數調用時引發異常失敗(當結果與「S_OK」值不同時)。 – TLama

+0

另請參閱示例[CodeAutomation.iss](https://woofy.googlecode.com/hg/tools/Inno%20Setup/Examples/CodeAutomation.iss)。 – Deanna

+0

@Deanna,在我發佈這個之前,我正在研究這個例子,但它是關於如何將節點追加到XML文件中,同時這是關於如何加載和保存現有節點值;-) – TLama