基于XML生成NI库SNPID报告脚本问题求助
解决多Flavour XML生成格式化TXT报告的问题
首先明确你的核心需求:从包含多SNPID、多<product>及<flavour>节点的XML文件中,生成格式为Library SNPID Number| Library Name | Registry Key | Library Path的TXT报告,要求列对齐、按数字升序排序,同时支持两种输出模式,还要解决UTF8无BOM输出的问题。
模式一:仅输出内部关联的Name与SNPID
这个模式下,我们只提取<flavour>节点内的Name和SNPID,同时继承所属<product>的Registry Key:
# 加载XML文件(替换为你的实际文件路径) $xmlPath = "你的库文件.xml" $xml = [xml](Get-Content $xmlPath -Raw) # 遍历所有<product>下的<flavour>,收集符合规则的数据 $reportData = foreach ($product in $xml.SelectNodes("//product")) { $productRegKey = $product.SelectSingleNode("registrykey")?.InnerText.Trim() foreach ($flavour in $product.SelectNodes("flavour")) { $name = $flavour.SelectSingleNode("name")?.InnerText.Trim() $snpId = $flavour.SelectSingleNode("snpid")?.InnerText.Trim() $libraryPath = $flavour.SelectSingleNode("librarypath")?.InnerText.Trim() # 仅当所有字段都存在时才添加 if ($name -and $snpId -and $productRegKey -and $libraryPath) { [PSCustomObject]@{ 'Library SNPID Number' = $snpId 'Library Name' = $name 'Registry Key' = $productRegKey 'Library Path' = $libraryPath } } } } # 按SNPID的数字部分升序排序(兼容含字母的SNPID) $sortedData = $reportData | Sort-Object { [int]($_.'Library SNPID Number' -replace '\D','') } # 生成对齐的文本内容(可根据实际内容调整列宽) $header = "Library SNPID Number| Library Name | Registry Key | Library Path" $separator = "-------------------|--------------|--------------|--------------" $content = $sortedData | ForEach-Object { $snpIdCol = $_. 'Library SNPID Number'.PadRight(19) $nameCol = $_. 'Library Name'.PadRight(14) $regKeyCol = $_. 'Registry Key'.PadRight(14) $pathCol = $_. 'Library Path' "$snpIdCol| $nameCol| $regKeyCol| $pathCol" } # 输出为UTF8无BOM格式文件 $fullContent = @($header, $separator) + $content if ($PSVersionTable.PSVersion.Major -ge 7) { $fullContent | Out-File -Path "报告_仅Flavour模式.txt" -Encoding utf8NoBOM -Force } else { # PowerShell 5及以下用.NET方法实现无BOM输出 [System.IO.File]::WriteAllLines("报告_仅Flavour模式.txt", $fullContent, [System.Text.UTF8Encoding]::new($false)) }
模式二:保留Product级条目同时输出Flavour内容
这个模式下,我们同时提取<product>级的Name/SNPID,以及<flavour>级的条目,所有<flavour>共享所属Product的Registry Key:
# 加载XML文件(替换为你的实际文件路径) $xmlPath = "你的库文件.xml" $xml = [xml](Get-Content $xmlPath -Raw) $reportData = @() # 先收集Product级别的条目 foreach ($product in $xml.SelectNodes("//product")) { $productRegKey = $product.SelectSingleNode("registrykey")?.InnerText.Trim() $productName = $product.SelectSingleNode("name")?.InnerText.Trim() $productSnpId = $product.SelectSingleNode("snpid")?.InnerText.Trim() $productPath = $product.SelectSingleNode("librarypath")?.InnerText.Trim() if ($productName -and $productSnpId -and $productRegKey -and $productPath) { $reportData += [PSCustomObject]@{ 'Library SNPID Number' = $productSnpId 'Library Name' = $productName 'Registry Key' = $productRegKey 'Library Path' = $productPath } } # 再收集该Product下的Flavour条目 foreach ($flavour in $product.SelectNodes("flavour")) { $flavourName = $flavour.SelectSingleNode("name")?.InnerText.Trim() $flavourSnpId = $flavour.SelectSingleNode("snpid")?.InnerText.Trim() $flavourPath = $flavour.SelectSingleNode("librarypath")?.InnerText.Trim() if ($flavourName -and $flavourSnpId -and $productRegKey -and $flavourPath) { $reportData += [PSCustomObject]@{ 'Library SNPID Number' = $flavourSnpId 'Library Name' = $flavourName 'Registry Key' = $productRegKey 'Library Path' = $flavourPath } } } } # 按SNPID的数字部分升序排序 $sortedData = $reportData | Sort-Object { [int]($_.'Library SNPID Number' -replace '\D','') } # 生成对齐文本 $header = "Library SNPID Number| Library Name | Registry Key | Library Path" $separator = "-------------------|--------------|--------------|--------------" $content = $sortedData | ForEach-Object { $snpIdCol = $_. 'Library SNPID Number'.PadRight(19) $nameCol = $_. 'Library Name'.PadRight(14) $regKeyCol = $_. 'Registry Key'.PadRight(14) $pathCol = $_. 'Library Path' "$snpIdCol| $nameCol| $regKeyCol| $pathCol" } # 输出UTF8无BOM文件 $fullContent = @($header, $separator) + $content if ($PSVersionTable.PSVersion.Major -ge 7) { $fullContent | Out-File -Path "报告_Product+Flavour模式.txt" -Encoding utf8NoBOM -Force } else { [System.IO.File]::WriteAllLines("报告_Product+Flavour模式.txt", $fullContent, [System.Text.UTF8Encoding]::new($false)) }
关键说明
- SNPID排序逻辑:脚本通过
-replace '\D',''提取SNPID中的纯数字部分,再转为整数排序,确保含字母的SNPID能按数字升序排列。 - 列对齐:用
PadRight手动设置列宽,你可以根据实际数据的长度调整数值,保证各列整齐对齐。 - UTF8无BOM输出:PowerShell 7+直接支持
utf8NoBOM编码参数,旧版本则借助.NET类实现无BOM的UTF8输出。 - 节点关联规则:严格遵循你提出的要求:
<flavour>继承所属<product>的Registry Key,Name和SNPID从对应节点内提取。
至于批处理脚本,由于它对XML的节点解析和复杂逻辑处理能力有限,很难优雅地处理多<flavour>的关联场景,因此更推荐使用上述PowerShell脚本。
内容的提问来源于stack exchange,提问作者ThDub
相关产品推荐
相关产品推荐

