使用powershell读取xml节点

时间:2018-05-28 14:21:25

标签: xml powershell

我需要通过powerShell从xml下面选择所有节点,其中application name =“secureApps”。

我正在使用以下脚本但收到错误。

$xml = [xml](Get-Content AppsConfiguration.xml)

foreach ($node in $xml.SelectNodes('/configurations/application/app')| Where 
$xml.configurations.application.name -eq "SecureApps" ) {

    $app_name = $node.app_name
    $app_path = $node.app_path

    # Create directory if not found
    if(-Not (Test-Path -Path $app_path)) {
    New-Item $app_path -Type Directory
    }

    # Convert directory to virtual directory
    New-WebVirtualDirectory -Site $secure_website_name.website_name -Name 
    $app_name -PhysicalPath $app_path

    $site_path = $secure_iis_site_location + $app_path
    ConvertTo-WebApplication -PSPath $site_path
}

问题在于:

foreach ($node in $xml.SelectNodes('/configurations/application/app')| Where $xml.configurations.application.name -eq "SecureApps" ) {

我使用的XML如下:

<?xml version="1.0"?>
<configurations>
<application name="SecureApps">
    <app id= "1">
        <app_name>atl</app_name>
        <app_path>D:\inetpub\secure\admin\atl</app_path>
    </app>
    <app id= "2">
        <app_name>corporate</app_name>
        <app_path>D:\inetpub\secure\admin\corporate</app_path>
    </app>
    <app id= "3">
        <app_name>f2l</app_name>
        <app_path>D:\inetpub\secure\admin\f2l</app_path>
    </app>
    <app id= "4">
        <app_name>GPModality</app_name>
        <app_path>D:\inetpub\secure\admin\GPModality</app_path>
    </app>
</application>
<application name="webApps">
    <app id= "1">
        <app_name>locations</app_name>
        <app_path>D:\inetpub\web\locations</app_path>
    </app>
</application>

1 个答案:

答案 0 :(得分:1)

这里有几个问题。

首先,您的where条件不起作用。如果使用没有脚本块的地方,则只有三个参数:当前管道对象的属性名称,比较运算符和固定值。

您在where条件中用作第一个参数的是一个表达式,该表达式提供包含字符串“SecureApps”和“webApps”的对象数组。

PowerShell期望包含属性名称的字符串作为where命令的第一个位置参数,无法将数组转换为此类字符串,因此会失败并显示错误消息。

尝试纠正此错误,同时保留简单的语法,您必须在管道对象中找到可以比较的属性。

您的管道对象是一个“app”XML节点,因此您可以尝试ParentNode.Name -eq ...但点缀属性也不能使用简单的where语法,只能使用普通的属性名称。

因此,要解决此特定问题,您可以回退到脚本块语法,如此

... | Where { $_.ParentNode.Name -eq "SecureApps" }

这不是最佳选择,因为您遍历每个app节点,然后才检查父application节点。最好首先过滤正确的application节点,然后浏览所有应用程序子节点:

foreach ($node in ($xml.configurations.application | Where name -eq "SecureApps").app ) {

Ansgar也有可能在他的评论中提到使用.NET SelectNodes使用XPath表达式这一事实,因此您可以使用XPath条件而不是PowerShell机制:

foreach ($node in $xml.SelectNodes("/configurations/application[@name='SecureApps']/app")) {