Удаление содержимого элемента XML в Inno Setup - PullRequest
2 голосов
/ 21 января 2020

Я пытаюсь преобразовать скрипт 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, '$1$2' | Set-Content -Encoding UTF8 $file
}

Эта часть скрипта PowerShell удаляет содержимое между ReportParametersLayout элементом файла RDL с регулярными выражениями для преобразования 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>

Что я должен сделать для удаления содержимого между XML элементом ReportParametersLayout, чтобы достичь этого результата в разделе кода?

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

Ответы [ 2 ]

2 голосов
/ 22 января 2020

Следующий код удалит узлы, выбранные 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/*');
1 голос
/ 21 января 2020

Я не могу точно понять, что делает ваше регулярное выражение, но вы можете очень легко очистить содержимое элемента xml, если проанализируете его с помощью правильного синтаксического анализатора 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, я бы посоветовал вам избегать регулярных выражений ради вашего будущего здравомыслия, если вам когда-нибудь придется вернуться к нему, чтобы внести изменения: -).

...