说我有这个XML:
<?xml version="1.0" encoding="utf-16"?>
<GPO xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.microsoft.com/GroupPolicy/Settings">
<Identifier>
<Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{0afca021-554a-49cf-adab-2b6241895145}</Identifier>
</Identifier>
<Name>DefaultName</Name>
<IncludeComments>true</IncludeComments>
<CreatedTime>2012-08-08T18:20:05</CreatedTime>
<ModifiedTime>2018-09-05T20:23:59</ModifiedTime>
<ReadTime>2018-09-19T11:02:17.4750654Z</ReadTime>
</GPO>
使用PowerShell,如何删除CreatedTime和ModifiedTime节点?
让我震惊的是GPO元素的名称空间问题。
这是我到目前为止所拥有的:
[xml]$xml = Get-Content "C:\temp\x.xml"
$parent_xpath = '//GPO'
$nodes = $xml.SelectNodes($parent_xpath)
$nodes
$nodes | % {
$child_node = $_.SelectSingleNode('CreatedTime')
$_.RemoveChild($child_node) | Out-Null
}
$xml.Save("C:\temp\x-2.xml")
exit
答案 0 :(得分:1)
您可以呼叫父节点,循环遍历每个子节点,然后从父节点中删除。您可以使用“ Node.ChildNode.ChildNode”定义父级
为您编写了一个快捷功能
function Remove-ChildNodes([xml]$FullXML, [string]$ParentNode, [string[]]$NodeNames){
return ($xml.$ParentNode.ChildNodes | ?{ $NodeNames -contains $_.Name }) | %{[void]$_.ParentNode.RemoveChild($_)}
}
这是工作副本
[xml]$xml=@"
<?xml version="1.0" encoding="utf-16"?>
<GPO xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.microsoft.com/GroupPolicy/Settings">
<Identifier>
<Identifier xmlns="http://www.microsoft.com/GroupPolicy/Types">{0afca021-554a-49cf-adab-2b6241895145}</Identifier>
</Identifier>
<Name>DefaultName</Name>
<IncludeComments>true</IncludeComments>
<CreatedTime>2012-08-08T18:20:05</CreatedTime>
<ModifiedTime>2018-09-05T20:23:59</ModifiedTime>
<ReadTime>2018-09-19T11:02:17.4750654Z</ReadTime>
</GPO>
"@
function Remove-ChildNodes([xml]$FullXML, [string]$ParentNode, [string[]]$NodeNames){
return ($xml.$ParentNode.ChildNodes | ?{ $NodeNames -contains $_.Name }) | %{[void]$_.ParentNode.RemoveChild($_)}
}
Remove-ChildNodes -FullXML $xml -ParentNode "GPO" -NodeNames "CreatedTime","ModifiedTime"
$xml.InnerXml
答案 1 :(得分:0)
考虑XSLT,这是一种专用于转换XML文件的专用语言,它可以处理默认的名称空间并删除元素而不会循环。 PowerShell可以与.NET的System.Xml.Xsl名称空间交互以运行XSLT 1.0脚本。
具体来说,在XSLT中,使用 gpo 在此处声明默认名称空间的前缀,然后运行identity transform以照原样复制整个文档,并为 CreatedTime传递空模板和 ModifiedTime 元素。因此,这些元素在文档中显示的任何位置都将被删除,而不会循环或引用父标记。另外,使用这种方法,如果您需要对XML进行其他设计更改,则可以轻松地在XSLT脚本中执行此操作,而无需触摸PowerShell脚本。
XSLT (另存为.xsl文件,一个特殊的.xml文件)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:gpo="http://www.microsoft.com/GroupPolicy/Settings">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- IDENTITY TRANSFORM -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- EMPTY TEMPLATES TO REMOVE -->
<xsl:template match="gpo:CreatedTime|gpo:ModifiedTime"/>
</xsl:stylesheet>
PowerShell
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load("C:\Path\To\XSLT_Script.xsl");
$xslt.Transform("C:\Path\To\Input.xml", "C:\Path\To\Output.xml");