在 Inno Setup 中删除 XML 元素的内容

Deleting content of XML element in Inno Setup

我正在尝试将 PowerShell 脚本转换为 Inno Setup Pascal 脚本代码。

$regularExpression=@'
(?ms)^(\s*  <ReportParametersLayout>\s*?\r?\n).*?\r?\n(\s*  </ReportParametersLayout>\s*)
'@

Foreach ($file in $files) {
    $text = (Get-Content $file) | Out-String 
    $text -replace $regularExpression, '' | Set-Content -Encoding UTF8 $file
}

这部分 PowerShell 脚本删除了 RDL 文件 ReportParametersLayout 元素之间的内容,其中包含用于将 SQL Server 2016 报告转换为 SQL Server 2008 的正则表达式。

<Report>
  ...
  <ReportParametersLayout>
    <GridLayoutDefinition>
      <NumberOfColumns>4</NumberOfColumns>
      <NumberOfRows>3</NumberOfRows>
      <CellDefinitions>
        <CellDefinition>
          <ColumnIndex>0</ColumnIndex>
          <RowIndex>0</RowIndex>
          <ParameterName>StartDate</ParameterName>
        </CellDefinition>
        <CellDefinition>
          <ColumnIndex>1</ColumnIndex>
          <RowIndex>0</RowIndex>
          <ParameterName>EndDate</ParameterName>
        </CellDefinition>
      </CellDefinitions>
    </GridLayoutDefinition>
  </ReportParametersLayout>
  ...
<Report>

我应该如何删除ReportParametersLayout的XML元素之间的内容才能在代码部分达到这个结果?

<Report>
  ...
  <ReportParametersLayout>
  </ReportParametersLayout>
  ...
</Report>

我无法确切地弄清楚你的正则表达式在做什么,但是如果你使用适当的 xml 解析器而不是正则表达式:

PS> $xml = [xml] @"
<ReportParametersLayout>
  <GridLayoutDefinition>
    <NumberOfColumns>4</NumberOfColumns>
    <NumberOfRows>3</NumberOfRows>
    <CellDefinitions>
      <CellDefinition>
        <ColumnIndex>0</ColumnIndex>
        <RowIndex>0</RowIndex>
        <ParameterName>StartDate</ParameterName>
      </CellDefinition>
      <CellDefinition>
        <ColumnIndex>1</ColumnIndex>
        <RowIndex>0</RowIndex>
        <ParameterName>EndDate</ParameterName>
      </CellDefinition>
    </CellDefinitions>
  </GridLayoutDefinition>
</ReportParametersLayout>
"@;

PS> $xml.DocumentElement.OuterXml # just to show the 'before' value
<ReportParametersLayout><GridLayoutDefinition><NumberOfColumns> ... etc ...

PS> $xml.DocumentElement.InnerText = "";

PS> $xml.DocumentElement.OuterXml
<ReportParametersLayout></ReportParametersLayout>

如果您要对 xml 进行任何其他修改,我建议您为了您未来的理智而避免使用正则表达式,如果您不得不返回它进行更改的话:-)。

以下代码将删除 XPath 选择的节点:

procedure DeleteNodes(FileName, Path: string);
var
  XMLDocument: Variant;
  XMLNodeList: Variant;
  Index: Integer;
begin
  XMLDocument := CreateOleObject('Msxml2.DOMDocument.6.0');
  try
    XMLDocument.async := False;
    XMLDocument.load(FileName);
    if XMLDocument.parseError.errorCode <> 0 then
    begin
      MsgBox('The XML file could not be parsed. ' +
        XMLDocument.parseError.reason, mbError, MB_OK)
    end
      else
    begin
      XMLDocument.setProperty('SelectionLanguage', 'XPath');
      XMLNodeList := XMLDocument.selectNodes(Path);
      for Index := 0 to XMLNodeList.length - 1 do
      begin
        XMLNodeList.item[Index].parentNode.removeChild(XMLNodeList.item[Index]);
      end;
      XMLDocument.save(FileName);
    end;
  except
    MsgBox('An error occured!' + #13#10 + GetExceptionMessage, mbError, MB_OK);
  end;
end;

您可以使用这样的函数来删除所有 <ReportParametersLayout> 个标签的所有子节点:

DeleteNodes('C:\some\path\my.xml', '//ReportParametersLayout/*');