我正在尝试解析一个名为 playlist.xml 的播放列表文件。我想从这个文件中过滤包含在 中的 和 .mp3 文件。实际上,$PlaylistPath 下有许多 playlist.xml 文件。我尝试使用 Get-Content、Select-String、Get-Childitem 和其他 cmdlet,但无济于事。下面显示的是我为此目的使用 PowerShell 的微不足道的尝试。
任何帮助将不胜感激!
$PlaylistPath = "\\MYNAS\Backups\Emby\Emby Backup - 2020-05-29 02.0.0 - Auto\playlists"
$OutputPath = "C:\Users\bernie\Desktop\playlists"
(Select-String -Path "C:\Users\bernie\Desktop\playlist.xml" -Pattern '^<Local').Line | Set-Content C:\Users\bernie\Desktop\Output.txt
# $FileNames = Get-Childitem -Path "playlists" -Include playlist.xml -File -Recurse | Select -exp Name
#$FileNames = Get-ChildItem $PlaylistPath -Filter playlist.xml -Recurse | % { $_.FullName }
foreach ($file in $FileNames) {
(Select-String -Path $file -Pattern 'LocalTitle').Line | Write-Output
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Item>
<Added>5/23/2020 9:49:16 PM</Added>
<LockData>false</LockData>
<LocalTitle>Andy Timmons Playlist</LocalTitle>
<RunningTime>32</RunningTime>
<Genres>
<Genre>Pop</Genre>
<Genre>Rock</Genre>
</Genres>
<Studios>
<Studio>Favored Nations Records</Studio>
</Studios>
<PlaylistItems>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/01 Deliver Us.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/02 Helipad.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/05 Redemption.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Ear X-Tacy/01 - Carpe Diem.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Ear X-Tacy/05 - Farmer Sez.mp3</Path>
</PlaylistItem>
</PlaylistItems>
</Item>
答案1
PowerShell:轻松解析 XML 元素值
首先,您提供的示例 XML 内容似乎格式不正确,因此我认为这只是一个粘贴问题,因此我通过关闭该示例中的</PlaylistItems>
和元素来更正它。</Items>
诀窍是使用获取内容读取 XML 文件的内容,然后将其设置为变量转换为 XML 数据类型. 然后你可以使用该变量的DocumentElement 方法明确遵循元素路径的其余部分从所需元素中获取值,这很简单。
因此,一旦你有了播放列表标题或名称和mp3 文件路径列表,您可以使用这些值进入文件或其他任何内容,但这是一种通过一些控制来解析 XML 文件的简单方法。
电源外壳
$PlaylistPath = "C:\Test\zzz\TestPlayList.xml";
[xml]$xml = Get-Content -LiteralPath $PlaylistPath;
$LocalTitle = $Xml.DocumentElement.LocalTitle;
$MP3Path = $Xml.DocumentElement.PlaylistItems.PlaylistItem.Path;
$LocalTitle;
$MP3Path;
全部playlist.xml
循环
$PlaylistPath = "C:\Test\zzz"
$XMLFiles = Get-ChildItem -LiteralPath $PlaylistPath -Include playlist.xml -File -Recurse;
$XMLFiles | % { Process {
[xml]$xml = Get-Content -LiteralPath $_.FullName;
$LocalTitle = $Xml.DocumentElement.LocalTitle;
$MP3Path = $Xml.DocumentElement.PlaylistItems.PlaylistItem.Path;
New-Item -Path "$OutputPath\$LocalTitle" -ItemType Directory -ErrorAction SilentlyContinue;
$MP3Path | % { Copy-Item -LiteralPath "\$($_.Replace("volume1", "ds418").Replace("/", "\"))" "$OutputPath\$LocalTitle"; };
##$LocalTitle;
##$MP3Path;
}};
输出(使用$LocalTitle
和$MP3Path
)
Andy Timmons Playlist
/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/01 Deliver Us.mp3
/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/02 Helipad.mp3
/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/05 Redemption.mp3
/volume1/Media Library/Music Library Bernie/Andy Timmons/Ear X-Tacy/01 - Carpe Diem.mp3
/volume1/Media Library/Music Library Bernie/Andy Timmons/Ear X-Tacy/05 - Farmer Sez.mp3
起始 XML
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Item>
<Added>5/23/2020 9:49:16 PM</Added>
<LockData>false</LockData>
<LocalTitle>Andy Timmons Playlist</LocalTitle>
<RunningTime>32</RunningTime>
<Genres>
<Genre>Pop</Genre>
<Genre>Rock</Genre>
</Genres>
<Studios>
<Studio>Favored Nations Records</Studio>
</Studios>
<PlaylistItems>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/01 Deliver Us.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/02 Helipad.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Resolution/05 Redemption.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Ear X-Tacy/01 - Carpe Diem.mp3</Path>
</PlaylistItem>
<PlaylistItem>
<Path>/volume1/Media Library/Music Library Bernie/Andy Timmons/Ear X-Tacy/05 - Farmer Sez.mp3</Path>
</PlaylistItem>
</PlaylistItems>
</Item>
支持资源
- 定义 PowerShell 数据类型
- 获取内容
- XmlDocument.DocumentElement 属性
- ForEach 对象
标准别名对于 Foreach 对象:'
%
' 符号,ForEach
答案2
皮条客果汁 IT,
以下是处理 Emby 播放列表文件的完整循环,引用我的 Synology NAS 上的 linux 路径,然后将它们转换为 windows 可以理解的 UNC 路径:
# These loops process the playlist.xml files.
$XMLFiles | % { Process {
[xml]$xml = Get-Content -LiteralPath $_.FullName
$LocalTitle = $Xml.DocumentElement.LocalTitle
Write-Host "Copying playlist music files to: " $OutputPath/$LocalTitle
New-Item -Path $OutputPath\$LocalTitle -ItemType Directory -ErrorAction SilentlyContinue | Out-Null
$MP3Path = $Xml.DocumentElement.PlaylistItems.PlaylistItem.Path
# This translates the Linux literal paths required by Get-Content and Copy-Item to UNC paths accessible in
# Windows. Also, most music files are prefixed with a number, cauing the playlists to out of sequence.
# A numeric prefix is prepended here to each music file resulting in a playing order consistent with the
# Emby playlist.
$counter = 1
foreach ($path in $MP3Path) {
$OutputFile = Split-Path $path -Leaf
$OutputFile = ([string]$counter).PadLeft(2,'0') + " - " + $OutputFile
$OutputFile = $OutputPath + "\" + $LocalTitle + "\" + $OutputFile
Copy-Item -LiteralPath "\$($path.Replace("volume1", "ds418").Replace("/", "\"))" $OutputFile
$counter++
}
}};
Write-Host "`nDone"