如何使用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中完全删除。

我真的很感激任何意见!

+0

这是clixml - 任何你不能使用Import-Clixml的原因,然后使用Where-Object? – JohnL 2012-07-20 15:29:46

+0

@ViConst - 在你的过滤器中,你说你想保留name_1和name_4,但在你的解释中,你提到你想保留name_2和name_4。请确认。 – dugas 2012-07-20 16:04:29

嘛,一开始你是不是分配变量$ 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") 
+0

完美,谢谢) – ViConst 2012-07-24 12:06:52

+0

我需要也保存所述第一节点' Selected.Microsoft.ActiveDirectory.Management.ADGroup System.Management.Automation.PSCustomObject系统。对象'如何过滤掉它呢? – ViConst 2012-07-25 08:41:11