Подтвердить что ты не робот

Как перебирать XML в Powershell?

У меня есть этот XML-документ в текстовом файле:

<?xml version="1.0"?>
<Objects>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="DisplayName" Type="System.String">SQL Server (MSSQLSERVER)</Property>
    <Property Name="ServiceState" Type="Microsoft.SqlServer.Management.Smo.Wmi.ServiceState">Running</Property>
  </Object>
  <Object Type="System.Management.Automation.PSCustomObject">
    <Property Name="DisplayName" Type="System.String">SQL Server Agent (MSSQLSERVER)</Property>
    <Property Name="ServiceState" Type="Microsoft.SqlServer.Management.Smo.Wmi.ServiceState">Stopped</Property>
  </Object>
</Objects>

Я хочу выполнить итерацию каждого объекта и найти DisplayName и ServiceState. Как мне это сделать? Я пробовал всевозможные комбинации и изо всех сил стараюсь это исправить.

Я делаю это, чтобы преобразовать XML в переменную:

[xml]$priorServiceStates = Get-Content $serviceStatePath;

где $serviceStatePath - это имя файла xml, показанное выше. Затем я подумал, что могу сделать что-то вроде:

foreach ($obj in $priorServiceStates.Objects.Object)
{
    if($obj.ServiceState -eq "Running")
    {
        $obj.DisplayName;
    }
}

И в этом примере мне нужна строка, выводимая с помощью SQL Server (MSSQLSERVER)

4b9b3361

Ответ 1

PowerShell имеет встроенные функции XML и XPath. Командлет Select-Xml можно использовать с запросом XPath для выбора узлов из объекта XML, а затем .Node. '# Text' для доступа к значению node.

[xml]$xml = Get-Content $serviceStatePath
$nodes = Select-Xml "//Object[Property/@Name='ServiceState' and Property='Running']/Property[@Name='DisplayName']" $xml
$nodes | ForEach-Object {$_.Node.'#text'}

Или короче

[xml]$xml = Get-Content $serviceStatePath
Select-Xml "//Object[Property/@Name='ServiceState' and Property='Running']/Property[@Name='DisplayName']" $xml |
  % {$_.Node.'#text'}

Ответ 2

Вы также можете сделать это без приведения [xml]. (Хотя xpath - это мир сам по себе. Https://www.w3schools.com/xml/xml_xpath.asp)

$xml = (select-xml -xpath / -path stack.xml).node
$xml.objects.object.property

Или только это, xpath чувствителен к регистру:

$xml = (select-xml -xpath /Objects/Object/Property -path stack.xml).node