2017-03-27 73 views
-2

我現在正在學習Powershell,所以請耐心等待。我想讀下面的XML清單使用PowerShell:從Powershell讀取XML文件/清單

<manifest desc="sql manifest"> 
    <projects> 
    <project project_directory="$/TFS/Main/branch/"> 
     <files> 
     <file filename="Shrink.sql"/> 
     <file filename="Users.sql"/> 
     </files> 
    </project> 
    <project project_directory="$/TFS/Main/branch/Pre/"> 
     <files> 
     <file filename="Logins.sql"/> 
     </files> 
    </project> 
    <project project_directory="$/TFS/Main/branch/Post/"> 
     <files> 
     <file filename="Security.sql"/> 
     </files> 
    </project> 
    </projects> 
</manifest> 

我期待的結果是這樣的:

 
$/TFS/Main/branch/Shrink.sql 
$/TFS/Main/branch/Users.sql 
$/TFS/Main/branch/Pre/Logins.sql 
$/TFS/Main/branch/Post/Security.sql 

你們能幫我PowerShell腳本?

$XmlDocument = Get-Content -Path "xmlfile.xml" 
+1

您是否已經爲「如何在PowerShell中解析XML文件」等主題做了一些基本的Google搜索? –

回答

1

如果刪除**字,下面的代碼應該返回自己想要的結果,假設你在同一目錄中的XML文件運行以下命令:

#### More than one directory 
$results = @() 

[xml]$XmlDocument = Get-Content .\xmlfile.xml 

$directoryCount = $XmlDocument.manifest.projects.project.Count 
$directoryNames = $XmlDocument.manifest.projects.project.project_directory 

for($i = 0 ; $i -lt $directoryCount; $i++) 
{ 
    $files = $XmlDocument.manifest.projects.project[$i].files.file 

    foreach($file in $files.filename) 
    { 
     $results += $directoryNames[$i] + $file 
    } 
} 

return $results 

#### Single Directory 
$results = @() 

[xml]$XmlDocument = Get-Content .\xmlfile.xml 

$directoryCount = @($XmlDocument.manifest.projects.project).Count 
$directoryNames = $XmlDocument.manifest.projects.project.project_directory 

for($i = 0 ; $i -lt $directoryCount; $i++) 
{ 
    $files = $XmlDocument.manifest.projects.project.files.file 

    foreach($file in $files.filename) 
    { 
     $results += $directoryNames + $file 
    } 
} 

return $results 

如果需要,你可以把這個變成功能,以消除一些重複代碼,並創建一個可重複使用的腳本:

<# 
.Synopsis 
    Gets XML file to parse and displays results 
.DESCRIPTION 
    Reads content of an XML file, parses the 
    manifest.projects.project.project_directory 
    tag and displays concatenated results of 
    project.project_directory and child file.filename 
    items 
.EXAMPLE 
    \Get-XMLFileItems -XMLFilePath "C:\users\myusername\desktop\myxmlfile.xml" 
.EXAMPLE 
    .\Get-XMLFileItems -XMLFilePath "C:\users\myusername\desktop\myxmlfile.xml" -MultipleDirectories $False 
#> 

[cmdletBinding()] 
Param(
    [Parameter(Mandatory=$true)] 
    [ValidateScript({Test-Path $_})] 
    [string]$XMLFilePath, 

    [Parameter()] 
    [bool]$MultipleDirectories = $true 
) 

BEGIN 
{ 
    Function Load-XMLFile 
    { 
     try 
     { 
      Write-Output "Loading XML file...`n" 
      [xml]$XMLDocument = Get-Content $XMLFilePath 

      Get-XMLDirectoryInfo -File $XMLDocument 

     } 
     catch [Exception] 
     { 
      Write-Error -Message "Error loading XML file $XMLFilePath" 
     } 
    } 

    Function Get-XMLDirectoryInfo($File) 
    { 
     try 
     { 
      $directoryCount = @($File.manifest.projects.project).Count 
     } 
     catch [Exception] 
     { 
      Write-Error "Unable to count 'manifest.projects.project' in schema" 
     } 

     try 
     { 
      $directoryNames = $File.manifest.projects.project.project_directory 
     } 
     catch [Exception] 
     { 
      Write-Error "Unable to find names for items in 'manifest.projects.project.project_directory' in schema" 
     } 

     Get-FilesInXMLSchema -File $File 
    } 

    Function Get-FilesInXMLSchema($File) 
    { 
     for($i = 0 ; $i -lt $directoryCount; $i++) 
     { 
      if($MultipleDirectories -eq $true) 
      { 
       $files = $File.manifest.projects.project[$i].files.file 

       foreach($item in $files.filename) 
       { 
        [array]$results += $directoryNames[$i] + $item 
       } 
      } 

      else 
      { 
       $files = $XmlDocument.manifest.projects.project.files.file 

       foreach($item in $files.filename) 
       { 
        [array]$results += $directoryNames + $item 
       } 
      } 
     } 

     Show-Results -InputObject $results 
    } 

    Function Show-Results($InputObject) 
    { 
     try 
     { 
      return $InputObject 
     } 
     catch [Exception] 
     { 
      Write-Error -Message "Error displaying results" 
     } 
    } 

    Function Write-Error($Message) 
    { 
     Write-Output $Message 
     $Error[0] 
     Write-Output "Exiting script" 
     Exit 
    } 
} 

PROCESS 
{ 
    Load-XMLFile 
} 

END 
{} 

如果不指定-MultipleDirectories參數,它會默認爲$ true。檢查使用開始處的幫助註釋。我對這兩個XML示例都進行了測試,並且它可以工作。希望這可以幫助!

+0

如果我在目錄上有多個計數,非常感謝這項工作。它不似乎是工作只有一個目錄: <清單DESC = 「SQL清單」> <項目project_directory = 「$/TFS /主/分公司/」> <文件名=「收縮.SQL「/> 有什麼建議? –

+0

Robin,我更新了我的響應,以包含兩種方案的方法,以及使用高級函數的腳本,您可以使用相同XML模式對文件重複使用該函數。如果您有任何問題,請告知我 – trebleCode

+0

謝謝user2734259。這工作。我將創建函數並讓主腳本調用它。 –