【问题标题】:Replacing only certain comments in xml using PowerShell使用 PowerShell 仅替换 xml 中的某些注释
【发布时间】:2021-10-27 13:32:18
【问题描述】:

我正在尝试取消注释第二个身份验证元素。但是,在取消注释 ' -->' 时,它会替换所有 ' -->' 元素。我们只希望取消注释第二个元素。

### Webconfig.xml ###
<webApi.webServer dateTimeZoneHandling="Local">
<!-- <authentication authenticationType="Windows" sessionTimeout="00:10:00" /> -->
<!-- <authentication authenticationType="Token" sessionTimeout="00:10:00" refreshTokenTimeout="99:00:00">
<tokenValidation validAudiences="e6b0f93b60250" securitykey="YmFzZT" validIssuers="WebApi"/>
</authentication> -->

Token_replace.ps1

    $web_service_config_path= [IO.Path]::Combine("D:\Scripts\Powershell","Web_Sample.config")
    $xml =  (Get-Content $web_service_config_path)
    $start_tag = $false
    $end_tag = $false
    foreach ($line in $xml) {  
        Write-Host $line
        $r = $line -match '^\s*<!--\s*<authentication authenticationType="Token"\s*sessionTimeout="00:10:00"\w*'
        Write-Host $r
        if($line -match '^\s*<!--\s*<authentication authenticationType="Token"\s*sessionTimeout="00:10:00"\w*' )
        {
            if($start_tag -eq $false)
            {
                $xml = $xml -replace '^\s*<!--\s*<authentication authenticationType="Token"\s*sessionTimeout="00:10:00"',  '<authentication authenticationType="Token" sessionTimeout="00:30:00"'
                $pattern = '</authentication>\s*-->'
            $start_tag = $true
            }      
        }
        if($line -match $pattern -and $start_tag -eq $true)
        {
            $xml = $xml -replace '</authentication>\s*-->', '</authentication>'
            $end_tag = $true
        }
        if($start_tag -eq $true -and $end_tag -eq $true)
        {
            break
        }
    }
    $xml|Out-File -FilePath "D:\Scripts\Powershell\Web_new.config"

【问题讨论】:

  • 您想取消对第二个&lt;!-- &lt;authentication authenticationType="Token" 的注释,同时也取消对&lt;/authentication&gt; --&gt; 的下一次出现的注释,或者只是取消对第二个的注释就可以了?
  • 我想取消注释下一次出现的 --> 以及...基本上是整个第二个身份验证块。
  • 我们还没有收到您的来信.. 任何给定的答案是否解决了您的问题?如果是这样,请通过单击左侧的 图标来考虑accepting。这将帮助其他有类似问题的人更轻松地找到它,并有助于激励其他人回答您将来可能遇到的任何问题。

标签: xml powershell


【解决方案1】:

我尝试了以下代码块,它对我有用。我逐行读取文件,同时将该行添加到另一个文件中。并在将其附加到另一个之前用注释替换该行。最终删除了原文件,并用原文件名重命名了新文件。

        $web_service_config_path= [IO.Path]::Combine("D:\Scripts\Powershell","Web.config")
    $xml =  (Get-Content $web_service_config_path)
    
    if(Test-Path ".\Web_new.config")
    {
        Remove-Item -Path ".\Web_new.config" -Force 
    }
    New-Item -ItemType File -Path ".\Web_new.config" -Force
    $start_tag = $false
    $end_tag = $false
    foreach ($line in $xml) 
    {  
        if($line -match '^\s*<!--\s*<authentication authenticationType="Token"\s*sessionTimeout="\d\d:\d\d:\d\d"\w*' )
        {
            $line = $line -replace '^\s*<!--\s*<authentication authenticationType="Token"\s*sessionTimeout="\d\d:\d\d:\d\d"',  '<authentication authenticationType="Token" sessionTimeout="00:40:00"'
            $start_tag = $true
                  
        }
        if($line -match '</authentication>\s*-->' -and $start_tag -eq $true -and $end_tag -eq $false)
        {
            $line = $line -replace '\s*</authentication>\s*-->', '</authentication>'
            $end_tag = $true
        }
        $line | Add-Content -Path ".\Web_new.config"
        if($start_tag -eq $true -and $end_tag -eq $true)
        {
            continue 
        }

       
    }
  
Remove-Item -Path ".\Web.config" -Force
Move-Item "Web_new.config" "Web.config" -Force

【讨论】:

    【解决方案2】:

    因为这是 XML,你不应该像那样使用字符串替换。

    要删除 xml 中的 ALL cmets,请使用 XmlReader 对象加载文件并设置该文件以忽略 cmets。然后重新保存文件以删除 cmets。

    $web_service_config_path = [IO.Path]::Combine("D:\Scripts\Powershell","Web_Sample.config")
    
    # create a XmlReaderSettings object and have it ignore comments 
    $settings = [System.Xml.XmlReaderSettings]::new()
    $settings.IgnoreComments = $true
    # create a XmlReader object pointing to your config file and using the XmlReaderSettings
    $reader = [System.Xml.XmlReader]::Create($web_service_config_path, $settings)
    # now load the config file in a new XmlDocument object using the XmlReader
    $xmlDocument = [System.XML.XMLDocument]::new()
    $xmlDocument.Load($reader)
    # dispose of the reader, otherwise the file cannot be overwritten
    $reader.Dispose()
    # and re-save the file
    $xmlDocument.Save($web_service_config_path)
    

    如果您选择性地想要删除注释标签&lt;authentication .../&gt;,您可以这样做:

    $web_service_config_path = [IO.Path]::Combine("D:\Scripts\Powershell","Web_Sample.config")
    # load the xml file
    $xmlDocument = [System.XML.XMLDocument]::new()
    $xmlDocument.Load($web_service_config_path)
    # select 'authentication' comments and remove them
    $xmlDocument.SelectNodes("//comment()[contains(.,'authentication')]") | ForEach-Object {
        $null = $_.ParentNode.removechild($_)
    }
    $xml.Save($web_service_config_path)
    

    contains() XPath 函数的第一个参数用于指定要执行比较的源节点或字符串。第二个参数是一个字符串,它指定要在源节点中查找的单词或字符串值。 请记住,contains() 函数区分大小写。

    【讨论】:

      猜你喜欢
      • 2023-02-01
      • 2023-03-22
      • 2019-05-26
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-25
      相关资源
      最近更新 更多