Спасибо Парфе, думаю, пришло время изучать XSLT :)
у меня есть следующий xml (items.xml), и я хочу найти атрибуты элемента дочернего узла, перебирать атрибуты, и, если я найду аналогичные атрибуты на уровне родительского узла, заменить их на атрибуты дочернего узла и удалить дочерние атрибуты. кроме имени.
<items>
<model type="model1" name="default" price="12.12" date="some_value">
<PriceData>
<item name="watch" price="24.28" date="2013-12-01" />
</PriceData>
</model>
<model type="model2" name="default" price="12.12" date="some_value">
<PriceData>
<item name="toy" price="22.34" date="2013-12-02"/>
</PriceData>
</model>
<model type="model3" name="default" price="12.12" date="some_value">
<PriceData>
<item name="bread" price="24.12" date="2013-12-03"/>
</PriceData>
</model>
</items>
Окончательный XML должен выглядеть следующим образом
<items>
<model type="model1" name="watch" price="24.28" date="2013-12-0">
<PriceData>
<item name="watch" />
</PriceData>
</model>
<model type="model2" name="toy" price="22.34" date="2013-12-02">
<PriceData>
<item name="toy" "/>
</PriceData>
</model>
<model type="model3" name="bread" price="24.12" date="2013-12-03">
<PriceData>
<item name="bread" />
</PriceData>
</model>
</items>
Я могу получить атрибуты на дочернем уровне, но не могу вернуться к родительскому узлу с дочернего уровня.
Ниже приведен код, который я пытался добраться до родительских узлов
[xml]$model = get-content items.xml
$model.SelectNodes("//item/@*")
Output:
#text
-----
watch
24.28
2013-12-01
toy
22.34
2013-12-02
bread
24.12
2013-12-03
$model.SelectNodes("//item/@*") | foreach {write-host $_.parentnode}
No Output:
$model.SelectNodes("//item/@*") | foreach {write-host $_.parentnode.parentnode}
No Output:
Я могу получить имена атрибутов дочернего узла следующим образом:
$model.SelectNodes("//item/@*") | foreach {write-host $_.name}
Output:
PS C:\BIOS_Work_Dir\Kit_Manifest_test> $model.SelectNodes("//item/@*") | foreach {write-host $_.name}
name
price
date
name
price
date
name
price
date
Теперь для каждого атрибута мне просто нужно вернуться к родительскому узлу, проверить, существует ли подобный атрибут, и заменить его атрибутом дочернего узла.
Итак, я ищу что-то вроде
$model.SelectNodes("//item/@*") | foreach {($_.name).parentnode.parentnode.($_.name)} | <some code to replace parentnode attribute with child attribute>
Затем удалить дочерние атрибуты что-то вроде
$model.SelectNodes("//item/@*") | where {$_.name -notlike "name"} | foreach {$_.Removeattribute()}
и если оба они могут быть сделаны в одной команде, что было бы здорово
Может быть, я также пытаюсь сделать много вещей в одной строке
Любые указатели очень ценятся! Не совсем уверен, что я делаю неправильно, поскольку powershell не выдает ошибку для использования родительского узла, а просто ничего не печатает. Любая помощь удивительна от всех вас опытных программистов!