Powershell - XML - Как извлечь несколько значений с разной глубины для каждого семейства узлов
Мне нужно проанализировать несколько миллионов строк XML. Для одного приложения я хочу извлечь 3 части данных для использования в других скриптах.
XML выглядит примерно так (несколько десятков тегов было удалено для каждой группы). Я могу изменить один из тегов имен, если это поможет; хотя и нежелательно, это потребует некоторой промежуточной обработки. Не все группы узлов имеют расширенные атрибуты.
<?xml version="1.0" encoding="IBM437"?>
<topo>
<node>
<name>device1Name</name>
<extendedAttributes>
<attribute>
<name>tagCategoryName</name>
<value>tagValue</value>
</attribute>
</extendedAttributes>
</node>
<node>
<name>device2Name</name>
<extendedAttributes>
<attribute>
<name>tagCategoryName</name>
<value>tagValue</value>
</attribute>
</extendedAttributes>
</node>
<node>
<name>device3Name</name>
</node>
...
...
</topo>
Результат, который я ищу для каждого узла:
deviceName tagCategoryName tagValue
Я пробовал несколько подходов и не смог найти элегантного решения. Началось с
$xml = [xml](get-content prodnodes.txt)
Пробовал использовать Select-Xml с xpath с прямым адресным конвейером $xml.topo.node для выбора объекта с использованием имен свойств. Я не смог эффективно настроить таргетинг на имена с помощью следующего.
$xml.topo.node | select-object -property name, extendedAttributes.attribute.name, extendedAttributes.attribute.value
Он вернет только имя. Следующее помогло мне получить дополнительный атрибут, но я не мог расширить его без проблем.
$munge = $xml.topo.node | select-object -property name, {$_.extendedAttributes.attribute.name}
Попытка продлить это выглядела так
$munge = $xml.topo.node | select-object -property name, {$_.extendedAttributes.attribute.name, $_.extendedAttributes.attribute.value}
который дал такой результат
deviceName1 {tagCategoryName1, tagValue1}
deviceName2 {tagCategoryName1, tagValue2}
deviceName3 {$null, $null}
deviceName4 {tagCategoryName2, tagValue3}
...
...
Есть ли способ очистить это или другой подход, более эффективный?
1 ответ
Ваш первый подход был почти правильным. При этом, чтобы копаться в подобных свойствах, вам нужно использовать вычисляемые свойства.
Вычисляемые свойства представлены хэш-таблицей, содержащей элемент name, который будет вашим именем столбца, и элементом выражения, который содержит блок сценария, чтобы сделать что-то большее, чем то, что вы можете с простым выбором.
Вот как вам нужно это сделать в своем сценарии.
Заявление
$xml.topo.node | select-object -property name,
@{'Name' = 'TagName' ; 'Expression' = { $_.extendedAttributes.attribute.name } },
@{'Name' = 'TagValue' ; 'Expression' = {$_.extendedAttributes.attribute.value}}
Результат
name TagName TagValue
---- ------- --------
device1Name tagCategoryName tagValue
device2Name tagCategoryName tagValue
device3Name
Дополнительная информация по этой теме
4sysops - Добавить вычисляемое свойство с помощью объекта select в powershell