这些天我正在学习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"
答案 0 :(得分: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示例测试了这个并且它可以工作。希望这有帮助!