使用powershell访问XML属性对于一个节点而不是另一个节点失败

时间:2016-07-27 03:23:01

标签: xml powershell xpath

所以我有这个函数,我用来从我的一个XML节点获取属性'type'。 XML文件中至少有两个这样的节点。

XML部分看起来像这样

<config>
  <local>
    <setup>
      <backup type="7Day"/>
        <folder name="Backups" type="backup_root">
          <folder name="DayTemplate" type="day_template">
            <folder name="Logs"/>
            <folder name="Objects">
              <folder name="Applications"/>
            </folder>
         </folder>
       </folder>
      </setup>
     </local>
    </config>

在我的下面的函数中,我传入了xml对象$ xmlDoc.config.local.setup,然后是我希望找到的'type'。用法类似于

$type = Get-FolderNameByType -folders $xmlDoc.config.local.setup -type 'day_template'

调试代码时我可以看到第一个文件夹类型'backup_root'。如果未能按预期匹配,但第二个'day_template'永远不会找到。由于某种原因,foreach循环跳过它,我不知道为什么。

function Get-FolderNameByType  
{
  param
  (
    [Object]
    $folders,

    [Object]
    $type
  )
  foreach ($folder in $folders.folder) 
  {
    if ( $folder.type ) 
    {
      if ( $folder.type -eq $type ) 
      {
        return $folder.name.tostring()
      }
    }
  }
}

我确信这个问题与我如何解析XML以及它在内存中的组织方式有关,但我无法弄明白。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

问题是您只枚举顶级文件夹,但您的文件夹结构是嵌套的,因此您只能看到'backup_root'。
您可以递归调用函数,也可以选择folder节点下面的所有$folders标记,这样可以这样做:

...
foreach ($folder in $folders.SelectNodes('//folder')) 
{
    if ($folder.type ...  

由于最后一个已经使用了XPath表达式,我们可以完全消除你的循环并像这样重写你的函数

function Get-FolderNameByType  
{
  param
  (
    [Object]
    $folders,

    [Object]
    $type
  )
  $folders.SelectNodes("//folder[@type='$type']")
}