#xml #powershell
#xml #powershell
Вопрос:
У меня есть два XML-файла.
File1.xml:
<fileAsset fileAssetGuid="guid1" assetTitle="Title1" />
<fileAsset fileAssetGuid="guid2" assetTitle="Title2" />
<fileAsset fileAssetGuid="guid3" assetTitle="Title3" />
File2.xml:
<file id="guid1" />
<file id="guid2" />
<file id="guid3" />
Я знаю значение assetTitle в File1.xml («Title1»). Мне нужно использовать это значение, чтобы получить / выбрать значение fileAssetGuid («guid1») в file1.xml . Затем мне нужно использовать значение («guid1») fileAssetGuid в file1.xml чтобы найти идентификатор («guid1») в file2.xml .
Как мне выполнить это в PowerShell?
Ответ №1:
Следующее должно делать то, что вы хотите (я добавил материал в иллюстративных целях):
PS D:MiLuDevPowerShell> cat .xmlsel1.xml
<file1>
<fileAsset fileAssetGuid="guid1" assetTitle="Title1" />
<fileAsset fileAssetGuid="guid2" assetTitle="Title2" />
<fileAsset fileAssetGuid="guid3" assetTitle="Title3" />
</file1>
PS D:MiLuDevPowerShell> cat .xmlsel2.xml
<file2>
<file id="guid1" data="one" />
<file id="guid2" data="two" />
<file id="guid3" data="three" />
</file2>
PS D:MiLuDevPowerShell> cat .xmlsel.ps1
$doc1 = [xml](get-content xmlsel1.xml)
$title = "Title2"
$asset = $doc1.file1.fileAsset | where { $_.assetTitle -eq $title }
# echo $asset
# echo $asset.assetTitle
# echo $asset.fileAssetGuid
$doc2 = [xml](get-content xmlsel2.xml)
$file = $doc2.file2.file | where { $_.id -eq $asset.fileAssetGuid }
# echo $file
echo $file.data
PS D:MiLuDevPowerShell> .xmlsel.ps1
two
Ответ №2:
Используйте Xpath.
# Load up the XML 1. I've used here-string, but anything goes.
[xml]$x1 = @'
<root>
<fileAsset fileAssetGuid="guid1" assetTitle="Title1" />
<fileAsset fileAssetGuid="guid2" assetTitle="Title2" />
<fileAsset fileAssetGuid="guid3" assetTitle="Title3" />
</root>
'@
# Ditto for XML 2.
[xml]$x2 = @'
<root>
<file id="guid1" />
<file id="guid2" />
<file id="guid3" />
</root>
'@
# Look for fileAsset element that has assettitle attribute
# which has value Title1
$n=$x1.SelectSinglenode("/root/fileAsset[@assetTitle='Title1']")
# Look for file node from XML2 that has id attribute
# that has value we got from XML1 with assetTitle
$x2.SelectSingleNode("/root/file[@id=`"$($n.fileAssetGuid)`"]")
# Remove the node by calling its parent's RemoveChild()
$n2.ParentNode.RemoveChild($n2)
# View final XML on the console
$x2.Save([console]::out)
Комментарии:
1. Рассмотрите возможность использования
Select-Xml
🙂2. Код удаления отлично сработал и в основном соответствует стилю, который я в итоге использовал в своем скрипте. Спасибо!
Ответ №3:
Следуя предложению Стеджея.
Select-Xml -Path "$pwdfile1.xml" -XPath "/root/fileAsset[@assetTitle]" |
ForEach {
$id = $_.Node.fileAssetGuid
Select-Xml -Path "$pwdfile2.xml" -XPath "/root/file[@id='$id']" |
ForEach { $_.Node }
}
############
############
foreach( $assetGuideRecord in (Select-Xml -Path "$pwdfile1.xml" -XPath "/root/fileAsset[@assetTitle]") ) {
$id = $assetGuideRecord.node.fileAssetGuid
foreach( $record in (Select-Xml -Path "$pwdfile2.xml" -XPath "/root/file[@id='$id']") ) {
$record.node
}
}
Комментарии:
1. Спасибо за ответы выше. Я попробовал метод Select-Xml, и у меня это сработало. Теперь, когда я выбрал узел <идентификатор файла =»guid1″ />, мне нужно удалить его из файла. Каков наилучший способ сделать это?
2. Найдите родительский узел для того, который вы хотите удалить, и удалите его дочерний узел. Согласно моему предыдущему ответу,
$n2 = $x2.SelectSingleNode("/root/file[@id=
«$($n.fileAssetGuid)"]"); $n2.ParentNode.RemoveChild($n2);$x2.Save([console]::out);
3. Смотрите мой обновленный ответ для синтаксиса удаления в более приятной форме.
4. Потрясающе! Заметил ваш обновленный ответ, который отлично сработал для меня. Спасибо!