Как сохранить значение CDATA с помощью Inno Setup в XML-файл? - PullRequest
0 голосов
/ 28 января 2019

Мне нужно сохранить значение CDATA в XML-файл с помощью Inno Setup.

Я ищу в документе Msxml2.DOMDocument.6.0, но безуспешно, как правильно записать значение в узел.

Если я попытаюсь просто объявить XMLNode.Text := AValue; со значением, которое я хочу ExpandConstant('<string><![CDATA[my value]]></string>); в своем коде, интерпретатор 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; 

Есть ли способ объявить раздел CDATA с помощью Msxml2.DOMDocument.6.0 с помощью Inno Setup?Я пробовал с экранированным символом, и он дал тот же результат также с синтаксисом 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; 

1 Ответ

0 голосов
/ 28 января 2019

createCDATASection - это метод «документа», а не «узла».

Это работает для меня:

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 должен выбрать внутренний узел string:

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

Результат:

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