删除包含特定属性的多个XML文件中的元素

时间:2017-12-05 21:46:24

标签: xml powershell xml-parsing

首先,我想引用this,因为它是基于PowerShell脚本进行微小修改的。

修改后的脚本(如下所示)的目标是遍历文件夹中的每个XML,如果它在对象中有一个对象,源文件以.eps结尾,则删除对象及其中的所有内容。从上面引用的链接,看起来好像我必须确保属性中的所有对象都被考虑在内。我试图使用通配符,当我运行它时,它没有弹出任何错误,但是,它也没有删除次要对象标记。

以下是对象/对象的示例XML:

<object class="graphic svg eps file_name:AR1.svg name:AR1" data="sample.svg"     height="100" type="image/svg+xml" width="100">
    <object class="graphic svg eps file_name:AR1.eps name:AR1" data="sample.eps" height="400" type="application/postscript" width="400">
        <p>NONE</p>
    </object>
</object>

以下是修改:

Get-ChildItem 'C:\test\*.xml' | ForEach-Object {
  $xml = [xml](Get-Content $_.FullName)

  $xml.SelectNodes("//object/object") | Where-Object {
    $_.class -eq "*" -and
    $_.data -eq "*.eps" -and
    $_.height -eq "*" -and
    $_.type -eq "application/postscript" -and
    $_.width -eq "*"
  } | ForEach-Object {
    $_.ParentNode.RemoveChildNode($_)
  }

  $xml.Save($_.FullName)
}

我的印象是通配符仍然有用,并且因为带有通配符的属性是随机的,基于XML文件名和图像文件名,使用通配符最好。

我仍然非常绿色,是PowerShell的新手,但感谢任何帮助。

编辑:

在@TheMadTechnician的帮助下,我已经将脚本更新到下面了!

    $items | ForEach-Object {
      $xml = [xml](Get-Content $_.FullName)

      $xml.SelectNodes("//*[@type='application/postscript']") | %{ $_.parentnode.removechild($_) }

      $xml.Save($_.FullName)

1 个答案:

答案 0 :(得分:2)

问题是您的Where声明不起作用。如果你只是运行该命令的第一部分,你可以看到这个:

$xml.SelectNodes("//object/object") | Where-Object {
  $_.class -eq "*" -and
  $_.data -eq "*.eps" -and
  $_.height -eq "*" -and
  $_.type -eq "application/postscript" -and
  $_.width -eq "*"
}

没有返回任何内容,因为只有其中一个评估为True,而这就是字面上等于你指示的类型

通配符非常棒,但您必须正确使用它们。 -eq运算符是文字的,不接受通配符。因此,当您$_.class -eq "*" $true$_.class时,*是仅包含-like的字符串。您可以使用这样的通配符的地方是$xml.SelectNodes("//object[contains(@data,'.eps') and @type='application/postscript']") | Where-Object { $_.data -like "*.eps" -and $_.type -eq "application/postscript" }|%{$_.parentnode.removechild($_)} 运算符。

$xml.SelectNodes("//object[contains(@data,'.eps') and @type='application/postscript']") | %{ $_.ParentNode.RemoveChild($_) }

这可以通过更好的XPath查询来简化:

[1,2,3,4,5][2,4,6,8,10]
[3,6,9,12,24][6,12,18,24,48]
....]