如何使用PowerShell过滤XML中的节点?
问题描述:
对于以下问题,我真的很感激您的帮助:如何使用PowerShell过滤XML中的节点?
XML数据存储在.xml文件中。
我想筛选出一些XML节点,如果他们有适当的“专有名称”(通过名称验证它)。
下面是XML结构:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>Selected.Microsoft.ActiveDirectory.Management.ADGroup</T>
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="Samaccountname">user.name</S>
<S N="distinguishedname">CN=Domain Users,CN=Users,DC=company,DC=com</S>
</MS>
<Obj RefId="1">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name1</S>
<S N="distinguishedname">CN=app_name_1,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="2">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name1</S>
<S N="distinguishedname">CN=app_name_2,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="3">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name2</S>
<S N="distinguishedname">CN=CN=app_name_3,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="4">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name2</S>
<S N="distinguishedname">CN=app_name_4,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
</Objs>
内容读取第一
$filedata = gc $Env:HOMEDRIVE\users.xml
然后过滤掉
$filedata = foreach ($obj in $filexml.Objs.Obj){
$obj.MS.S | ?{ $_.N -eq "distinguishedname"} |
%{if($_."#text" -match "*name_1" -or $_."#text" -match "*name_4*")
{$obj}}}
在我的例子<Obj RefId="2">
和<Obj RefId="4">
都OK了,应该是过滤,并<Obj RefId="0">
和<Obj RefId="1">
应该从XML中完全删除。
我真的很感激任何意见!
答
嘛,一开始你是不是分配变量$ filexml的东西,所以你可能需要
$filexml = [xml] fileData
如果你还没有使用PowerShell ISE调试代码,你错过了,设置断点在您的foreach会显示你的$ FileXml变量是空
而且你的XML是无效的,应该是
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>Selected.Microsoft.ActiveDirectory.Management.ADGroup</T>
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="Samaccountname">user.name</S>
<S N="distinguishedname">CN=Domain Users,CN=Users,DC=company,DC=com</S>
</MS>
</Obj>
<Obj RefId="1">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name1</S>
<S N="distinguishedname">CN=app_name_1,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="2">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name1</S>
<S N="distinguishedname">CN=app_name_2,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="3">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name2</S>
<S N="distinguishedname">CN=CN=app_name_3,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="4">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name2</S>
<S N="distinguishedname">CN=app_name_4,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
</Objs>
+0
对!我只是错过了$ filexml = [xml] fileData。谢谢! – ViConst 2012-07-24 11:51:26
答
假设下面的XML和旅途人是去除所有的OBJ REFID不等于2和4:
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
<Obj RefId="0">
<TN RefId="0">
<T>Selected.Microsoft.ActiveDirectory.Management.ADGroup</T>
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="Samaccountname">user.name</S>
<S N="distinguishedname">CN=Domain Users,CN=Users,DC=company,DC=com</S>
</MS>
</Obj>
<Obj RefId="1">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name1</S>
<S N="distinguishedname">CN=app_name_1,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="2">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name1</S>
<S N="distinguishedname">CN=app_name_2,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="3">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name2</S>
<S N="distinguishedname">CN=CN=app_name_3,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
<Obj RefId="4">
<TNRef RefId="0" />
<MS>
<S N="Samaccountname">user.name2</S>
<S N="distinguishedname">CN=app_name_4,OU=publ,OU=app,DC=comp,DC=com</S>
</MS>
</Obj>
</Objs>
定义过滤器:
$filters = [regex]".*(name_2|name_4).*"
装载XML:
$xml = [xml](Get-Content "$home\Documents\test.xml")
删除不需要的元素:
$xml.Objs.Obj | ?{ ($_.MS.S | ?{$_.N -eq "distinguishedname"}).'#text' -notmatch $filters} | %{$xml.Objs.RemoveChild($_)}
保存xml:
$xml.Save("$home\Documents\test2.xml")
这是clixml - 任何你不能使用Import-Clixml的原因,然后使用Where-Object? – JohnL 2012-07-20 15:29:46
@ViConst - 在你的过滤器中,你说你想保留name_1和name_4,但在你的解释中,你提到你想保留name_2和name_4。请确认。 – dugas 2012-07-20 16:04:29