PowerShell嵌套foreach循环处理哈希表生成正确HTML标记问题
解决有序哈希表解析的HTML标记错误问题
现有一个不可修改的有序哈希表数据结构,尝试用foreach循环解析生成类HTML标记时,出现了结构错误:子项未被OpenRow/CloseRow包裹、标记不完整等问题。
原错误代码
$Data5 = [ordered]@{ 'LocalInfo' = [ordered]@{ 'Date' = '21.12.2024'; 'SysName' = 'Jopa213' }; 'Baseboard(1155)' = [ordered]@{ 'Manufacturer' = 'Asus'; 'Model' = 'P5BPro'; 'RAM Slots' = '4' }; 'CPU0' = [ordered]@{ 'Name' = 'Intel Core i-5 2500'; 'Cores/Threads' = '4/4'; }; 'RAM(DDR3)' = [ordered]@{ 'SLOT01' = [ordered]@{ 'Name' = 'DIMM01'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; 'SLOT02' = [ordered]@{ 'Name' = 'DIMM02'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; 'SLOT03' = [ordered]@{ 'Name' = 'DIMM03'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; 'SLOT04' = [ordered]@{ 'Name' = 'DIMM01'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; } 'HDD01' = [ordered]@{ 'Bus(Type)' = '(SATA)HDD'; 'Name' = 'Toshiba 101'; 'Size' = '500 Gb'; 'Status' = 'Healty'; }; 'HDD02' = [ordered]@{ 'Bus(Type)' = '(NVMe)SSD'; 'Name' = 'Samsung Evo'; 'Size' = '128 Gb'; 'Status' = 'Healty'; }; 'GPUs' = [ordered]@{ 'GPU0' = [ordered]@{ 'Name' = 'nVIDIA Vanta 8Mb'; 'RAM' = '1024 Mb'; }; 'GPU1' = [ordered]@{ 'Name' = 'ATI Radeon RX7'; 'RAM' = '2048 Mb'; }; }; 'NetCard01' = [ordered]@{ Name = 'Realtek Jopa Edition 1Gb'; MAC = '00:11:22:33:44:55' }; 'NetCard02' = [ordered]@{ Name = 'Intel Bebra Edition 2Gb'; MAC = '11:44:44:44:55:66' }; 'NetConnection01' = [ordered]@{'Name' = 'NetConnection01(Active)'; 'MAC' = '11:44:44:44:55:66'; 'IPAddress' = '192.168.0.32'; 'SubNetMask' = '255.255.255.0'; 'Gateway' = '192.168.0.1'; }; 'NetConnection02' = [ordered]@{'Name' = 'NetConnection01(Active)'; 'MAC' = '11:44:44:44:55:66'; 'IPAddress' = '192.168.0.32'; 'SubNetMask' = '255.255.255.0'; 'Gateway' = '192.168.0.1'; }; OpertatingSystem = [ordered]@{ 'Name' = 'MacroHard Lindows 10.2'; 'Version' = '10.2.1923'; }; } $Open = "OpenRow" $Close = "CloseRow" foreach ($HashTable in $Data5) { foreach ($L1Key in $HashTable.Keys) { Write-host $Open $L1Key $Close foreach ($L2Key in $HashTable.$L1Key.Keys) { IF ($HashTable.$L1Key.$L2Key.GetType() -like "*String*") { Write-Host "OpenDiv" $HashTable.$L1Key.$L2Key "CloseDiv" } ELSEIF ($HashTable.$L1Key.$L2Key.GetType() -like "*Dictionary*") { Write-Host "OpenRow" foreach ($L3Key in $HashTable.$L1Key.$L2Key.Keys) { Write-Host "OpenDiv" $L3Key "CloseDiv" } Write-Host "CloseRow" } } } }
原错误输出示例
OpenRow LocalInfo CloseRow ---问题:下方两行未用OpenRow包裹 OpenDiv 21.12.2024 CloseDiv OpenDiv Jopa213 CloseDiv ---问题:未用CloseRow闭合 OpenRow Baseboard(1155) CloseRow
修正后的代码
$Data5 = [ordered]@{ 'LocalInfo' = [ordered]@{ 'Date' = '21.12.2024'; 'SysName' = 'Jopa213' }; 'Baseboard(1155)' = [ordered]@{ 'Manufacturer' = 'Asus'; 'Model' = 'P5BPro'; 'RAM Slots' = '4' }; 'CPU0' = [ordered]@{ 'Name' = 'Intel Core i-5 2500'; 'Cores/Threads' = '4/4'; }; 'RAM(DDR3)' = [ordered]@{ 'SLOT01' = [ordered]@{ 'Name' = 'DIMM01'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; 'SLOT02' = [ordered]@{ 'Name' = 'DIMM02'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; 'SLOT03' = [ordered]@{ 'Name' = 'DIMM03'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; 'SLOT04' = [ordered]@{ 'Name' = 'DIMM01'; 'Size' = '1024 Mb'; 'Speed' = '800 Mhz' }; } 'HDD01' = [ordered]@{ 'Bus(Type)' = '(SATA)HDD'; 'Name' = 'Toshiba 101'; 'Size' = '500 Gb'; 'Status' = 'Healty'; }; 'HDD02' = [ordered]@{ 'Bus(Type)' = '(NVMe)SSD'; 'Name' = 'Samsung Evo'; 'Size' = '128 Gb'; 'Status' = 'Healty'; }; 'GPUs' = [ordered]@{ 'GPU0' = [ordered]@{ 'Name' = 'nVIDIA Vanta 8Mb'; 'RAM' = '1024 Mb'; }; 'GPU1' = [ordered]@{ 'Name' = 'ATI Radeon RX7'; 'RAM' = '2048 Mb'; }; }; 'NetCard01' = [ordered]@{ Name = 'Realtek Jopa Edition 1Gb'; MAC = '00:11:22:33:44:55' }; 'NetCard02' = [ordered]@{ Name = 'Intel Bebra Edition 2Gb'; MAC = '11:44:44:44:55:66' }; 'NetConnection01' = [ordered]@{'Name' = 'NetConnection01(Active)'; 'MAC' = '11:44:44:44:55:66'; 'IPAddress' = '192.168.0.32'; 'SubNetMask' = '255.255.255.0'; 'Gateway' = '192.168.0.1'; }; 'NetConnection02' = [ordered]@{'Name' = 'NetConnection01(Active)'; 'MAC' = '11:44:44:44:55:66'; 'IPAddress' = '192.168.0.32'; 'SubNetMask' = '255.255.255.0'; 'Gateway' = '192.168.0.1'; }; OpertatingSystem = [ordered]@{ 'Name' = 'MacroHard Lindows 10.2'; 'Version' = '10.2.1923'; }; } $Open = "OpenRow" $Close = "CloseRow" # 遍历主哈希表的键值对,获取每个分类的名称和对应的子数据 foreach ($mainItem in $Data5.GetEnumerator()) { $mainKey = $mainItem.Key $subHash = $mainItem.Value # 输出主分类行 Write-Host "$Open $mainKey $Close" # 遍历子哈希表的键值对 foreach ($subItem in $subHash.GetEnumerator()) { $subKey = $subItem.Key $subValue = $subItem.Value if ($subValue -is [string]) { # 字符串类型:用OpenRow/CloseRow包裹Div Write-Host "$Open" Write-Host "OpenDiv $subValue CloseDiv" Write-Host "$Close" } elseif ($subValue -is [System.Collections.IDictionary]) { # 字典类型:先输出子分类行,再遍历其内部键值对 Write-Host "$Open $subKey $Close" foreach ($innerItem in $subValue.GetEnumerator()) { Write-Host "$Open" Write-Host "OpenDiv $($innerItem.Value) CloseDiv" Write-Host "$Close" } } } }
修正说明
- 遍历方式调整:用
GetEnumerator()遍历哈希表,直接获取键值对,避免原逻辑中遍历Value导致的层级混乱 - 字符串子项处理:所有字符串类型的子项都用
OpenRow和CloseRow包裹,确保标记结构完整 - 字典子项层级优化:对于嵌套的字典(如RAM(DDR3)下的SLOT),先输出子分类的行标记,再遍历内部的字符串值,保持结构一致性
正确输出示例片段
OpenRow LocalInfo CloseRow OpenRow OpenDiv 21.12.2024 CloseDiv CloseRow OpenRow OpenDiv Jopa213 CloseDiv CloseRow OpenRow Baseboard(1155) CloseRow OpenRow OpenDiv Asus CloseDiv CloseRow OpenRow OpenDiv P5BPro CloseDiv CloseRow OpenRow OpenDiv 4 CloseDiv CloseRow
内容的提问来源于stack exchange,提问作者alive-one
相关产品推荐
相关产品推荐

