【问题标题】:Change XML tags within PowerShell and keep content.在 PowerShell 中更改 XML 标记并保留内容。
【发布时间】:2012-01-20 23:56:20
【问题描述】:

我已经使用 PowerShell 从 EventLog 导出数据,并创建了一个示例架构以将数据导入 SQL,但是使用 ConvertToXML 从 PowerShell 导出数据的方式存在问题。

XML 的导出如下所示;

<Property Name="Version">0</Property>

<Property Name="Qualifiers" />

<Property Name="Level">0</Property>

<Property Name="Task">14339</Property>

<Property Name="Opcode">0</Property>

<Property Name="Keywords">-9218868437227405312</Property>

<Property Name="RecordId">57963203</Property>

<Property Name="ProviderName">Microsoft-Windows-Security-Auditing</Property>

但它应该看起来像这样;

<Version>0</Version>

<Qualifiers> />

<Level>0</Level>

<Task>14339</Task>

下面的代码标识了属性名称版本和属性标签的开始和结束 并尝试将其更改为但不幸的是它更改了它而不将内容保留在标签内。我似乎无法保持价值。

$EventLog = (Get-WinEvent -ComputerName xxxxxxx-FilterXML $Query) | ConvertTo-Xml -NoTypeInformation

$EventLogModify = (Get-Content P:\EventTracking\Events.xml) | foreach{$_ -replace '(<Property Name=""Version"">(.*?)</Property>)', "<Version></Version>" };Set-Content P:\EventTracking\Events.xml $EventLogModify;

【问题讨论】:

    标签: xml regex powershell replace


    【解决方案1】:

    你的问题出在

    -replace '(<Property Name=""Version"">(.*?)</Property>)', "<Version></Version>"
    

    您将一个完整的标签替换为一个空标签。我猜你想在替换中使用捕获的组:

    -replace '(<Property Name=""Version"">(.*?)</Property>)', '<Version>$2</Version>'
    

    此外,您之前可能在正则表达式中使用了双引号,因为那里有 ""。这可能不会匹配任何内容,因为它现在会连续查找两个双引号。

    另一件事,你可能想一次全部替换,所以可以使用这个:

    -replace '<Property Name="([^"]+)">([^<]+)</Property>', '<$1>$2</$1>'
    

    但这还不够:

    PS> $xml -replace '<Property Name="([^"]+)">([^<]+)</Property>', '<$1>$2</$1>'
    <Version>0</Version>
    <Property Name="Qualifiers" />
    <Level>0</Level>
    <Task>14339</Task>
    <Opcode>0</Opcode>
    <Keywords>-9218868437227405312</Keywords>
    <RecordId>57963203</RecordId>
    <ProviderName>Microsoft-Windows-Security-Auditing</ProviderName>
    

    如您所见,Qualifiers 仍未更改。所以另一个替换:

    -replace '<Property Name="([^"]+)"\s*/>','<$1/>'
    

    现在看起来好多了

    PS> $xml -replace '<Property Name="([^"]+)">([^<]+)</Property>', '<$1>$2</$1>' -replace '<Property Name="([^"]+)"\s*/>','<$1/>'
    <Version>0</Version>
    <Qualifiers/>
    <Level>0</Level>
    <Task>14339</Task>
    <Opcode>0</Opcode>
    <Keywords>-9218868437227405312</Keywords>
    <RecordId>57963203</RecordId>
    <ProviderName>Microsoft-Windows-Security-Auditing</ProviderName>
    

    【讨论】:

    • 哇。那绝对是美丽的。这是我现在的代码; $EventLogModify = (获取内容 P:\EventTracking\Events.xml) | foreach{$_ -replace '([^', '$2$1>' -replace '','' };Set-Content P:\EventTracking\Events.xml $EventLogModify;非常感谢。
    • 这真是太棒了。非常感谢。这是我的最终代码;
    • 嗯,正确的方法可能是使用 XML API,但由于你所拥有的实际上并不是 XML,这有点棘手。本质上,您必须用另一个标签包围 sn-p,将其全部解析为 XML,将属性转换为 DOM 中的元素名称,然后再次将其写入 XML,然后将其去除现在多余的周围标签。不好,不好玩,但可能比使用正则表达式更安全(尽管我认为你在那里做的事情已经足够安全了)。
    【解决方案2】:

    另一种简单的方法:

    [Xml]$xml=@'
    <root>
    <Property Name="Version">0</Property>
    <Property Name="Qualifiers" />
    <Property Name="Level">0</Property>
    <Property Name="Task">14339</Property>
    <Property Name="Opcode">0</Property>
    <Property Name="Keywords">-9218868437227405312</Property>
    <Property Name="RecordId">57963203</Property>
    <Property Name="ProviderName">Microsoft-Windows-Security-Auditing</Property>
    </root>
    '@
    
    
    
    $xml.SelectNodes('//Property') | ForEach `
     -begin { 
           $h = New-Object xml
           $r = $h.CreateElement("ROOT")
           $null=$h.AppendChild($r)
       } `
     -process {
         if($_.'#text') {
             $n = $h.CreateElement($_.Name)
             $n.InnerText = $_.'#text'
             $null=$r.AppendChild($n)
         }
         else {
            $n = $h.CreateElement($_.Name)
            $null=$r.AppendChild($n)
          }
        } `
     -End {
          $h.OuterXml
          }
    

    或:

    $xml.SelectNodes('//Property')|% {
    if($_.'#text') { "<{0}>{1}</{0}>" -f $_.name,$_.'#text' } else {"<$($_.name)/>"}
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 1970-01-01
      • 2016-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多