如何使用 Inno Setup 将 CDATA 值保存到 XML 文件中?

How to save CDATA value with Inno Setup into XML file?

我需要通过 Inno Setup 将 CDATA 值保存到 XML 文件中。

我搜索了 Msxml2.DOMDocument.6.0 文档,但关于将值正确写入节点的方法没有成功。

如果我尝试在代码中使用我想要的值 ExpandConstant('<string><![CDATA[my value]]></string>); 声明 XMLNode.Text := AValue;,XML 解释器会将所有字符 '<>' 替换为 XML 个实体 &lt;&gt;

function SaveValueToXML(const AFileName, APath, AValue : 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');
      XMLDocument.setProperty(
        'SelectionNamespaces', 'xmlns:ns=''urn:mathworks.matlab.settings''');
      XMLNode := XMLDocument.selectSingleNode(APath);
      XMLNode.Text := AValue;
      XMLDocument.save(AFileName);      
    end;
  except
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK);
  end;
end;

function NextButtonClick(PageID: Integer): Boolean;
var
  XMLFile: string;
begin
  Result := True;
  if (PageId = wpReady) then 
  begin
    XMLFile := ExpandConstant('path to xml file');
    if FileExists(XMLFile) then 
    begin
      SaveValueToXML(
        XMLFile, '//ns:key[@name=''InstallationFolder'']',
        ExpandConstant('&lt;![CDATA[value to write]]&gt;&lt;/string&gt;'));      
    end;
  end;
end; 

有没有办法在 Inno Setup 中用 Msxml2.DOMDocument.6.0 声明 CDATA 部分?我尝试使用转义字符,但使用 XMLNode := XMLNode.createCDATASection(Avalue); 语法也产生了相同的结果,但没有成功...

XML 文件包含:

<?xml version="1.0" encoding="UTF-8"?>
<settings name="matlab" visible="true" xmlns="urn:mathworks.matlab.settings" xsi:schemaLocation="urn:mathworks.matlab.settings settings.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <!-- ... -->
    <settings name="addons">
        <!-- ... -->
        <key name="InstallationFolder">
            <string></string>
        </key>
    </settings>
</settings>

并且我们需要将代码XML修改为:

<?xml version="1.0" encoding="UTF-8"?>
<settings name="matlab" visible="true" xmlns="urn:mathworks.matlab.settings" xsi:schemaLocation="urn:mathworks.matlab.settings settings.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <!-- ... -->
    <settings name="addons">
        <!-- ... -->
        <key name="InstallationFolder">
            <string>
                <value><![CDATA[my value]]></value>
            </string>
        </key>
    </settings>
</settings>

最终代码:

const
  NODE_ELEMENT = 1; 

(*Function to load and save value to an XML file*)
function SaveValueToXML(const AFileName, APath, AValue : string): string;
var
  XMLNode: Variant;
  XMLNode2: 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');
      XMLDocument.setProperty('SelectionNamespaces', 'xmlns:ns=''urn:mathworks.matlab.settings''');
      XMLNode := XMLDocument.selectSingleNode(APath);
      XMLNode2 := XMLDocument.createNode(NODE_ELEMENT, 'value', 'urn:mathworks.matlab.settings');
      XMLNode2.appendChild(XMLDocument.createCDATASection(AValue));
      XMLNode.appendChild(XMLNode2);      
      XMLDocument.save(AFileName);     
    end;
  except
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK);
  end;
end;

function NextButtonClick(PageID: Integer): Boolean;
var
  XMLFile: string;
begin
  Result := True;
  if (PageId = wpReady) then 
  begin
    XMLFile := ExpandConstant('{userappdata}\MathWorks\MATLAB\R2018b\matlab.settings');
    if FileExists(XMLFile) then 
    begin
      SaveValueToXML(XMLFile, '//ns:key[@name=''InstallationFolder'']/ns:string', ExpandConstant('{userappdata}\MathWorks\MATLAB Add-Ons'));      
    end;
  end;
end; 

createCDATASection 是 "document" 的方法,而不是 "node".

的方法

这对我有用:

XMLNode.appendChild(XMLDocument.createCDATASection(AValue));

整个代码,包括 value 节点的创建:

const
  NODE_ELEMENT = 1;
XMLNode2 := XMLDocument.createNode(NODE_ELEMENT, 'value', 'urn:mathworks.matlab.settings');
XMLNode2.appendChild(XMLDocument.createCDATASection('my value'));
XMLNode.appendChild(XMLNode2); 

此外,您的 XPath 需要 select 内部 string 节点:

//ns:key[@name='InstallationFolder']/ns:string

结果:

<key name="InstallationFolder">
    <string>
        <value><![CDATA[my value]]></value></string>
</key>