You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell:在ForEach-Object中正确处理哈希表生成.url文件

解决从XML生成Windows .url文件的循环处理问题

问题背景

需要从给定的XML文件生成对应的Windows .url快捷方式文件,已尝试将标题和URL存入有序哈希表,但循环处理时无法正确获取每一对标题和URL,要么所有内容拼接成一串,要么变量为空。

相关文件与代码

XML文件内容

<?xml version="1.0" encoding="UTF-16" ?>
<items_list>
<item>
<title>About topics - PowerShell | Microsoft Learn</title>
<url>https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about?view=powershell-7.3</url>
</item>
<item>
<title>PowerShell HashTable - Everything you need to know — LazyAdmin</title>
<url>https://lazyadmin.nl/powershell/powershell-hashtable/</url>
</item>
<item>
<title>How a Regex Engine Works Internally</title>
<url>https://www.regular-expressions.info/engine.html</url>
</item>
</items_list>

原哈希表构建代码

$InXML = [XML](Get-Content .\test.xml)
$BookMarks = [ordered]@{
Title = (Select-Xml -xml $InXML -XPath "//title" | % {$_.Node.InnerXml}) -replace '\?|\\|/|:'
URL   = Select-Xml -xml $InXML -XPath "//url" | % {$_.Node.InnerXml}
}

原循环处理代码(存在问题)

$wshshell = New-Object -ComObject WScript.Shell
$BookMarks | ForEach-Object {
    $Title = $_.Title
    $Url = $_.Url
    Write-Output $shortcutFilePath
    # $shortcutFilePath = Join-Path -path "c:\temp" -ChildPath "$Title.Url"
    # $shortcut = $shell.CreateShortcut($shortcutFilePath)
    # $shortcut.TargetPath = "$Url"
    # $shortcut.Save()
}

问题分析

原哈希表结构错误:$BookMarks中的Title和URL各自是包含所有条目值的数组,而非一一对应的键值对集合。用ForEach-Object遍历该哈希表时,实际遍历的是哈希表的两个键(Title和URL),无法同时获取同一item对应的标题和URL。此外,原代码还存在变量未定义($shell应为$wshshell)、提前输出未赋值变量的问题。

解决方法

方法一:直接遍历XML节点(推荐)

无需构建哈希表,直接遍历XML中的每个<item>节点,天然获取对应标题和URL,代码更简洁直观:

# 读取XML时指定UTF-16编码,避免乱码
$InXML = [XML](Get-Content .\test.xml -Encoding UTF16)
$wshshell = New-Object -ComObject WScript.Shell
$outputPath = "c:\temp"

# 遍历每个item节点
foreach ($item in $InXML.items_list.item) {
    # 清理标题中的非法字符(Windows文件名不允许?\/:)
    $cleanTitle = $item.title -replace '\?|\\|/|:', ''
    $shortcutFilePath = Join-Path -Path $outputPath -ChildPath "$cleanTitle.url"
    
    # 创建并保存.url快捷方式
    $shortcut = $wshshell.CreateShortcut($shortcutFilePath)
    $shortcut.TargetPath = $item.url
    $shortcut.Save()
}

方法二:构建正确的哈希表数组

如果需要保留哈希表结构,需将每个item转换为独立的哈希表并存入数组,确保循环时能获取每一对标题和URL:

$InXML = [XML](Get-Content .\test.xml -Encoding UTF16)
# 构建包含单个item信息的哈希表数组
$BookMarks = foreach ($item in $InXML.items_list.item) {
    [ordered]@{
        Title = $item.title -replace '\?|\\|/|:', ''
        URL   = $item.url
    }
}

$wshshell = New-Object -ComObject WScript.Shell
$outputPath = "c:\temp"

# 遍历哈希表数组,处理每个item
$BookMarks | ForEach-Object {
    $shortcutFilePath = Join-Path -Path $outputPath -ChildPath "$($_.Title).url"
    $shortcut = $wshshell.CreateShortcut($shortcutFilePath)
    $shortcut.TargetPath = $_.URL
    $shortcut.Save()
}

内容的提问来源于stack exchange,提问作者hellen_dorandt89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:30:52