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

问题描述:

我已经使用PowerShell从EventLog中导出数据,并创建了一个示例模式以将数据导入SQL,但是存在使用ConvertToXML从PowerShell导出数据的方式问题。在PowerShell中更改XML标签并保留内容。

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; 

你的问题是

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

哇。这绝对是美丽的。这是我现在的代码; $ EventLogModify =(Get-Content P:\ EventTracking \ Events.xml)| foreach {$ _ -replace'([^ ',' $ 2$1>'-replace'',''}; Set-Content P:\ EventTracking \ Events.xml $ EventLogModify; 非常感谢。 – 2011-12-15 10:11:47

另一种简单的方法:

[Xml][email protected]' 
<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)/>"} 
}