【问题标题】:How to filter out nodes in XML using PowerShell?如何使用 PowerShell 过滤掉 XML 中的节点?
【发布时间】:2012-07-19 20:46:02
【问题描述】:

非常感谢您对以下问题的任何帮助:

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

在我的示例中,&lt;Obj RefId="2"&gt;&lt;Obj RefId="4"&gt; 正常,应该被过滤,&lt;Obj RefId="0"&gt;&lt;Obj RefId="1"&gt; 应该从 XML 中完全删除。

我非常感谢任何建议!

【问题讨论】:

  • 那是 clixml - 有什么理由不能使用 Import-Clixml,然后使用 Where-Object?
  • @ViConst - 在您的过滤器中,您说您想要保留 name_1 和 name_4,但在您的解释中,您提到您想要保留 name_2 和 name_4。请验证。

标签: xml powershell powershell-2.0


【解决方案1】:

好吧,首先你没有将变量 $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>

【讨论】:

  • 对!我只是错过了 $filexml = [xml] fileData。谢谢!
【解决方案2】:

假设如下xml,目标是移除所有不等于2和4的Obj RefId:

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

【讨论】:

  • 我还需要保存第一个节点&lt;TN RefId="0"&gt; &lt;T&gt;Selected.Microsoft.ActiveDirectory.Management.ADGroup&lt;/T&gt; &lt;T&gt;System.Management.Automation.PSCustomObject&lt;/T&gt; &lt;T&gt;System.Object&lt;/T&gt; &lt;/TN&gt;如何过滤掉它?
猜你喜欢
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
相关资源
最近更新 更多