PowerShell синтаксический анализ XML не работает для одной записи - PullRequest
0 голосов
/ 10 января 2019

Я создал скрипт для анализа всех имен серверов из файла XML. Работает нормально при наличии более 1 записи.

Почему-то скрипт не работает, если в XML есть только одна запись.

Вот XML:

<Env>
<Web>
    <sr id="Server001"></sr>
    <sr id="Server002"></sr>
    <sr id="Server003"></sr>
</Web>
</Env>

Вот скрипт PowerShell:

# Load servers list 
$pth =  "C:\Support\Auto\Config_xml\TEST.xml"
[xml]$css = Get-Content $pth
#
Write-Host "Preparing servers list...."
$sra = @()
for ($i=0; $i -le $css.Env.Web.sr.Length -1; $i++) {
    $svn = $css.Env.Web.sr[$i].id
    $sra += $svn
}
$sra

Кто-нибудь посоветует, в чем причина проблемы?

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Ваш код не работает, когда существует только один <sr> узел, потому что в этом случае $css.Env.Web.sr не возвращает массив. Возвращенный узел не имеет свойства Length (или Count), поэтому ваш цикл for просто пропускается.

Вот почему практически всегда предпочтительнее использовать SelectNodes() (или SelectSingleNode()) с выражениями XPath.

$sra = $css.SelectNodes('//sr') | Select-Object -Expand id

Добавьте оператор подвыражения массива, если вам нужно, чтобы $sra был массивом независимо от количества <sr> узлов:

$sra = @($css.SelectNodes('//sr') | Select-Object -Expand id)
0 голосов
/ 10 января 2019

Устраните такую ​​проблему, как показано в коде ниже в ISE или VSCode. Обратите внимание, как я сбросил тип, чтобы увидеть, что происходит.

x1
Object[]
x2
XmlElement

Также, используя foreach, обрабатывает массивы и отдельные объекты ...

$x1 = [xml]@'
<Env>
<Web>
    <sr id="Server001"></sr>
    <sr id="Server002"></sr>
    <sr id="Server003"></sr>
</Web>
</Env>
'@

"x1"
$x1.Env.Web.sr.GetType().Name

$x2 = [xml]@'
<Env>
<Web>
    <sr id="Server004"></sr>
</Web>
</Env>
'@

"x2"
$x2.Env.Web.sr.GetType().Name

"foreach1"
foreach($item in $x1.Env.Web.sr)
{
    "ID is $($item.id)"
}

"foreach2"
foreach($item in $x2.Env.Web.sr)
{
    "ID is $($item.id)"
}
...