【问题标题】:Removing Child In XML Via PowerShell?通过 PowerShell 删除 XML 中的子项?
【发布时间】:2019-04-23 14:56:57
【问题描述】:

我已经搜索了所有地方以找到此问题的答案,但我似乎找不到适合我的答案,是的,我知道这已经被问了很多,但没有任何工作。

这是我的代码:

$Request = Invoke-RestMethod ($BaseURL + $StatPage) -WebSession  $Session -Method Post -Body $StatBody
$Request = $Request | Where-Object {$_.'mac' -ne "00:00:00:00:00:00"}

我什至尝试过,而不是删除节点,而是将其打印出来:

foreach($Node in $Request.'ajax-response'.response.'acl-list'.acl.deny)
{
     if($Node.'mac' -eq "00:00:00:00:00:00")
     {
         $Node.ParentNode.RemoveNode($Node)
     }
}

这会产生好的旧错误:Collection was of a fixed size.

我尝试了其他几个但不再有代码,MAC 有效并且在列表中,并通过保存和检查验证了这一点。

这里有一些例子XML

我需要使用 XML,因为 API 只支持它,我真的碰壁了,希望得到一些帮助:)

【问题讨论】:

  • $Request 的类型是什么。 $Request.GetType() ?
  • 似乎很奇怪,首先您过滤 $Request 以不具有值为 "00:00:00:00:00:00" 的元素 .mac ,然后再循环请求以找到删除这些元素(即$Request 中不存在,因为您已将它们过滤掉..)
  • 文档类型是Xml Document,我不控制这个api,需要保持文档的结构,不能只取出mac数组

标签: .net xml powershell


【解决方案1】:

出现错误Collection was of a fixed size. 表明您可能正在使用集合\数组而不是 XML 元素。

您可以将Invoke-RestMethod 输出显式转换为 XmlDocument:

[xml] $Request = Invoke-RestMethod ($BaseURL + $StatPage) -WebSession  $Session -Method Post -Body $StatBody

并在要删除的节点上调用方法RemoveChild()

foreach($Node in $Request.'ajax-response'.response.'acl-list'.acl.deny)
{
     if($Node.'mac' -eq "00:00:00:00:00:00")
     {
         $Node.ParentNode.RemoveChild($Node)
     }
}

如果您对RemoveChild() 给出的输出不感兴趣,可以将其通过管道传递给 null:

$Node.ParentNode.RemoveChild($Node) | Out-Null

【讨论】:

  • 这可以正常工作,但是当我在 RemoveChild 之后输出 $Request 时,它会保留应该删除的元素。
  • 啊,我想我在调用 .Save("") 保存到文件后得到了它,理想情况下我想这样做而不必保存到文件,但我想这可行很好:)。
【解决方案2】:

我不知道这是否会对您有所帮助,但这就是我所做的。我使用了您链接中的数据:

<ajax-request action="updobj" comp="acl-list" updater="blocked-clients">
    <acl id="1" name="System" description="System" default-mode="allow" EDITABLE="false">
        <deny type="single" mac="c0:bd:d1:14:62:68"/>
        <deny mac="c0:d3:c0:1c:60:93" type="single"/>
        <deny type="single" mac="b4:74:43:c0:f3:cf"/>
        <deny type="single" mac="c0:ee:fb:25:ca:7c"/>
        <deny type="single" mac="48:db:50:ed:71:36"/>
        <deny mac="d4:50:3f:fd:48:2f" type="single"/>
        <deny type="single" mac="58:48:22:c2:44:2e"/>
    </acl>
</ajax-request>

然后我做了以下,只是循环数据并创建没有不需要的mac的新文件:

 [xml]$xml = Get-Content "C:\Users\b.moeskops\Desktop\test.xml"
    $data = $xml.'ajax-request'.acl.deny
    $wrongData = "c0:d3:c0:1c:60:93"

    foreach($Node in $data){
        if($Node.'mac' -eq $wrongData){
            $data = $data | Where-Object {$_.mac -ne $wrongData} 
        }
    }
    $data

我希望这会有所帮助。

【讨论】:

  • 确实如此!但是我需要保持 xml 文档的其余部分完好无损,而不是只创建一个新列表
  • 除了转换成字符串并在其周围填充其余的 XML 之外,您还有其他想法吗?
【解决方案3】:

我可能找到了一些有用的东西...... 我再次使用了您链接中的数据。

$Path = "H:\test.xml"
$xml = Get-Content $Path

$array = $xml | ConvertTo-Json | ConvertFrom-Json

foreach($obj in $array.value){
    if($obj -match '<deny type="single" mac="c0:bd:d1:14:62:68"/>' -or $obj -match '<deny mac="c0:d3:c0:1c:60:93" type="single"/>'){
        $array2 = $array.value | Where-Object {$_ -ne $obj}
    }
}
$array2

首先是文件:

 <ajax-request action="updobj" comp="acl-list" updater="blocked-clients">
    <acl id="1" name="System" description="System" default-mode="allow" EDITABLE="false">
        <deny type="single" mac="c0:bd:d1:14:62:68"/>
        <deny mac="c0:d3:c0:1c:60:93" type="single"/>
        <deny type="single" mac="b4:74:43:c0:f3:cf"/>
        <deny type="single" mac="c0:ee:fb:25:ca:7c"/>
        <deny type="single" mac="48:db:50:ed:71:36"/>
        <deny mac="d4:50:3f:fd:48:2f" type="single"/>
        <deny type="single" mac="58:48:22:c2:44:2e"/>
    </acl>
</ajax-request>

此文件保存在“H:\test.xml”。运行脚本后,$array2 的输出为:

$array2
<ajax-request action="updobj" comp="acl-list" updater="blocked-clients">
    <acl id="1" name="System" description="System" default-mode="allow" EDITABLE="false">
        <deny type="single" mac="c0:bd:d1:14:62:68"/>
        <deny type="single" mac="b4:74:43:c0:f3:cf"/>
        <deny type="single" mac="c0:ee:fb:25:ca:7c"/>
        <deny type="single" mac="48:db:50:ed:71:36"/>
        <deny mac="d4:50:3f:fd:48:2f" type="single"/>
        <deny type="single" mac="58:48:22:c2:44:2e"/>
    </acl>
</ajax-request>

如果您检查该文件,您会发现我已从文件中删除了内容并保持格式不变。

如您所见,我删除了 XML 文件的两行,这样做是因为在文件中找到了 2 种不同的格式。

希望这会有所帮助!

【讨论】:

  • 这并不像看起来那么简单,GetType() 对保存我的 XML 的变量的结果是 XmlDocument,但是当我运行此代码时,我没有得到任何输出,也没有我是否得到任何返回的列表,看来我的 powershell 想让这对我来说不可能:(
猜你喜欢
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多