在PowerShell

时间:2019-07-23 17:26:42

标签: powershell

我在PowerShell中具有以下代码:

[xml]$Xml = @"
<?xml version="1.0" encoding="utf-8"?>
<Sequences>
  <Sequence>
    <SequenceName>Sequence-A</SequenceName>
    <SequencePackages>
      <Package>
        <PackageFolder>Package-A</PackageFolder>
        <PackageActive>False</PackageActive>
      </Package>
      <Package>
        <PackageFolder>Package-B</PackageFolder>
      </Package>
    </SequencePackages>
  </Sequence>
  <Sequence>
    <SequenceName>Sequence-B</SequenceName>
    <SequencePackages>
      <Package>
        <PackageFolder>Package-C</PackageFolder>
        <PackageMeta>
          <PackageStart>2019-07-23T18:53:58.392+02:00</PackageStart>
          <PackageEnd>2019-07-23T18:53:58.392+02:00</PackageEnd>
        </PackageMeta>
      </Package>
      <Package>
        <PackageFolder>Package-D</PackageFolder>
        <PackageMeta>
          <PackageStart>2019-07-23T18:53:58.407+02:00</PackageStart>
          <PackageEnd>2019-07-23T18:53:58.407+02:00</PackageEnd>
        </PackageMeta>
      </Package>
    </SequencePackages>
  </Sequence>
</Sequences>
"@

Clear-Host

$Sequences = $Xml.Sequences.Sequence | Where-Object ...
$Sequences

如您所见,我加载XML数据,然后要使用“ Where-Object”对其进行过滤。 在XML中,我们看到2个Sequence节点,每个节点包含2个package-node。

我要选择具有以下内容的“序列”节点:

  • 至少一个活动包。当存在(NO节点)或(IS TRUE)时,包是活动的 (在示例中,Package-A未激活)
  • 至少一个包裹没有结束时间(属性“ PackageEnd”)

在此示例中,查询结果应为“ Sequence-A”,因为它确实有一个包,该包不包含属性“ PackageActive”,并且两个包都没有结束时间(属性“ PackageEnd”为未设置)。

理想情况下,我正在寻找单线飞机...

提前感谢您的支持!

编辑: 我确实添加了更多示例以进行澄清...

[xml]$Xml = @"
<?xml version="1.0" encoding="utf-8"?>
<Sequences>
  <Sequence>
    <SequenceName>Sequence-A</SequenceName>
    <SequencePackages>
      <Package>
        <PackageFolder>Package-A</PackageFolder>
        <PackageActive>False</PackageActive>
      </Package>
      <Package>
        <PackageFolder>Package-B</PackageFolder>
      </Package>
    </SequencePackages>
  </Sequence>
  <Sequence>
    <SequenceName>Sequence-B</SequenceName>
    <SequencePackages>
      <Package>
        <PackageFolder>Package-C</PackageFolder>
        <PackageMeta>
          <PackageEnd>2019-07-23T18:53:58.392+02:00</PackageEnd>
        </PackageMeta>
      </Package>
      <Package>
        <PackageFolder>Package-D</PackageFolder>
        <PackageMeta>
          <PackageEnd>2019-07-23T18:53:58.407+02:00</PackageEnd>
        </PackageMeta>
      </Package>
    </SequencePackages>
  </Sequence>
  <Sequence>
    <SequenceName>Sequence-C</SequenceName>
    <SequencePackages>
      <Package>
        <PackageFolder>Package-E</PackageFolder>
        <PackageActive>False</PackageActive>
      </Package>
      <Package>
        <PackageFolder>Package-F</PackageFolder>
        <PackageMeta>
          <PackageEnd>2019-07-23T18:53:58.407+02:00</PackageEnd>
        </PackageMeta>      
      </Package>
    </SequencePackages>
  </Sequence>
  <Sequence>
    <SequenceName>Sequence-D</SequenceName>
    <SequencePackages>
      <Package>
        <PackageFolder>Package-G</PackageFolder>
        <PackageActive>True</PackageActive>
      </Package>
      <Package>
        <PackageFolder>Package-H</PackageFolder>
      </Package>
    </SequencePackages>
  </Sequence>  
</Sequences>
"@
  • 应该选择顺序-A。不会处理Package-A,但Package-B不包含PackageEnd节点。
  • 不应选择序列B。这两个软件包都包含一个PackageEnd节点。
  • 不应选择序列C。 Package-E无效,并且Package-F包含PackageEnd-node。
  • 应该选择序列-D。 Package-G是活动的,Package-H也是如此。这两个软件包都不包含PackageEnd节点。

2 个答案:

答案 0 :(得分:1)

您应该可以很容易地将其通过管道传递到where-object过滤器。我使用了第二个xml示例。也许可以更好地设计xml。 Packagemeta不会显示在$ xml.sequences.sequence.sequencepackages.package下,除非您将其通过管道传递给format-list。我只将外部foreach放在& { }的旁边,以便您可以通过它进行管道操作。

& { 
  foreach ($s in $xml.sequences.sequence) {
    foreach ($p in $s.sequencepackages.package) {
      [pscustomobject] @{
        sequencename = $s.sequencename
        packagefolder = $p.packagefolder
        packageactive = $p.packageactive
        packageend = $p.packagemeta.packageend
      }
    }
  } 
}


sequencename packagefolder packageactive packageend
------------ ------------- ------------- ----------
Sequence-A   Package-A     False
Sequence-A   Package-B
Sequence-B   Package-C                   2019-07-23T18:53:58.392+02:00
Sequence-B   Package-D                   2019-07-23T18:53:58.407+02:00
Sequence-C   Package-E     False
Sequence-C   Package-F                   2019-07-23T18:53:58.407+02:00
Sequence-D   Package-G     True
Sequence-D   Package-H

答案 1 :(得分:0)

以下一线似乎是解决方案:

$Sequences = $Xml.Sequences.SelectNodes( "//Sequence[.//Package[(./PackageActive/text()='True' or not(./PackageActive)) and not(.//PackageEnd)]]" )