#xml #powershell
#xml #powershell
Вопрос:
У меня есть следующий xml:
<messages>
<message name="Advertisement" msgtype="7" msgcat="app">
<field name="AdvId" required="Y" />
<field name="AdvTransType" required="Y" />
<field name="AdvRefID" required="N" />
<component name="Instrument" required="Y" />
<field name="AdvSide" required="Y" />
<field name="Quantity" required="Y" />
</message>
</messages>
<components>
<component name="Instrument">
<field name="Symbol" required="Y" />
<field name="SymbolSfx" required="N" />
<field name="SecurityID" required="N" />
<field name="SecurityIDSource" required="N" />
<group name="NoSecurityAltID" required="N">
<field name="SecurityAltID" required="N" />
<field name="SecurityAltIDSource" required="N" />
</group>
<field name="Product" required="N" />
<field name="CFICode" required="N" />
</component>
</components>
Я хочу перебирать каждое сообщение, и когда я сталкиваюсь с component
тегом, я хочу заменить компонентный xml на поля / группы компонента.
Я пытался использовать ReplaceChild
, но он работал не так, как ожидалось.
[void]LoadComponents() {
$this.xml.messages.message | ForEach-Object {
$m = $_
foreach ($node in $m.ChildNodes){
if ($node.LocalName -eq "component") {
Write-Host "Old Message: "
Write-Host ($m.field | Format-Table | Out-String)
$c = $this.GetComponent($node.name)
Write-Host "Component: "
Write-Host ($c.group | Format-Table | Out-String)
$m.ReplaceChild($c, $node)
Write-Host "New Message: "
Write-Host ($m.field | Format-Table | Out-String)
}
}
}
}
[System.Xml.XmlElement]GetComponent([string]$name) {
return $this.xml.components.component | Where-Object { $_.name -eq $name }
}
Редактировать:
Я включаю тот факт, что я использую powershell версии 6.0.0.10 alpha в OSX, потому что, по-видимому, в нем отсутствует много функций.
Ответ №1:
Используйте XPath для непосредственного выбора узлов компонентов и клонирования узла замены в replaceChild.
$xml.SelectNodes('/root/messages/message/component') | ForEach {
$comp = $xml.SelectSingleNode('/root/components/component[@name="' $_.name '"]')
$message = $_.ParentNode
$message.ReplaceChild($comp.Clone(), $_)
}
Код предполагает, что корневой узел root
.
Комментарии:
1. Спасибо @wOxxOm, но я получаю
[System.Xml.XmlDocument] does not contain a method named 'SelectNodes'
2. версия powershell:
6.0.0 alpha
3. Я не использую глючные / неполные альфа-версии, поэтому понятия не имею, как он мог пропустить такую базовую функциональность. Это так же абсурдно, как строка без indexOf .