在PowerShell中更改XML标记并保留内容。

时间:2011-12-15 09:04:18

标签: xml regex powershell replace

我使用PowerShell从EventLog导出数据,并创建了一个示例Schema来将数据导入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;

2 个答案:

答案 0 :(得分:3)

你的问题在

-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>

答案 1 :(得分:0)

另一种简单的方法:

[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)/>"}
}