2015-01-19 5 views
3

Я пытаюсь разобрать XML, который не состоит из равномерных атрибутов. ПримерАнализ несогласованных XML-объектов с использованием Powershell

<root> 
<object> 
    <name>Object1</name> 
    <valueString>string</valueString> 
</object> 
<object> 
    <name>Object2</name> 
    <valueBoolean>true</valueBoolean> 
</object> 
</root> 

Количество дополнительных атрибутов всегда то же самое, но иногда его логическое значение, и иногда его строка и имя тега изменяется соответствующим образом. Проблема заключается не в самом типе, а в Powershell, я должен знать имя тега заранее, чтобы получить прикрепленное к нему значение.

На данный момент я делаю что-то вроде этого:

foreach($item in $items){ 
    if(!$item.object.valueString){ 
    $temp = $item.object.valueBoolean 
    } 
    else{ 
    $temp = $item.object.valueString 
    } 
    $properties = @{ 
     Name = $item.object.Name 
     value = $temp 
    } 
} 

Это работает, но я хотел бы более элегантное решение + на данный момент это довольно жесткая, и вы должны обслуживать каждую возможность.

Есть ли лучший способ?

Приветствия

ответ

2

Вы можете использовать ChildNodes свойство для доступа к дочерним элементам по их порядку:

$xml=[xml]@' 
<root> 
    <object> 
    <name>Object1</name> 
    <valueString>string</valueString> 
    </object> 
    <object> 
    <name>Object2</name> 
    <valueBoolean>true</valueBoolean> 
    </object> 
</root> 
'@ 
foreach($object in $xml.root.object){ 
    $value=$object.ChildNodes[1] 
    [PSCustomObject]@{ 
     Name=$object.Name 
     ValueName=$value.Name 
     Value=$value.'#text' 
    } 
} 
+0

легенда человек !! .. $ object.ChildNode [x]. '# text' ftw – GradiusX

1

Это не обязательно решить общую проблему странного XML барахла, но вспомогательная функция, чтобы сливаться различные возможности могли бы сделать вещи триммер. Проверено:

function value ($parent) { 
    :args foreach ($name in $args) { 
     $v = $parent.$("value$name") 
     if ($v -ne $null) {$v; break args} 
    } 
} 

И использовать его как value ($item.object) Boolean String, предполагая, что все эти узлы имеют один и тот же шаблон valueXXX. (Если они всегда из фиксированного набора, вы можете обрезать использование ниже, используя жесткое кодирование, которое установлено вместо $args.Если есть намного больше вариаций, чем valueXXX, вам нужно настроить соответствующую вспомогательную функцию.)

Объяснение: Использует $args, чтобы захватить все неназванные аргументы, затем прокручивается, строит объект доступа на лету от интерполяции строк и находит первый ненулевой результат, который затем возвращается. Петля помечена как раз для того, чтобы быть уверенным.

Смежные вопросы