如何使用 csv 列标题 powershell 获取 xml 字段值 [英] How to get xml field value using csv column header powershell
问题描述
当我使用 for 循环然后在代码 ({ $_.'field_name' -eq $b} 中添加值 $b 时,它给出的是空值而不是结果.
When I use for loop and then add value $b here in code ({ $_.'field_name' -eq $b} then it's giving blank value instead of result.
$CSVpath = "G:\1.csv"
$columncount=((Get-Content $CSVpath)[0] -split ",").count
write-host $columncount
$xml= "G:\1.xml"
[xml] $xmlDoc = Get-Content $xml
for($i=0; $i -le $columncount;$i++){
$a = ((Get-Content $CSVpath)[0] -split(','))[$i]
$b= "'$a'"
Function xml{
param($value)
$xml= "G:\1.xml"
[xml] $xmlDoc = Get-Content $xml
$a1= $xmlDoc.enum_types.enum_type.Where({ $_.'field_name' -eq $b}, 'First').items.item.where({ $_.id -eq 1}).value
$d = $a1.'#cdata-section'
write-host $d
}
xml $b
}
请帮我解决问题.请找到xml:
Please help me to resolve issue. Please find xml:
<enum_types>
<enum_type field_name="Test1">
<items>
<item>
<id>1</id>
<value>A</value>
</item>
</items>
</enum_type>
<enum_type field_name="Test2">
<items>
<item>
<id>1</id>
<value>A</value>
</item>
</items>
</enum_type>
</enum_types>
请找到 csv 文件:
Please find csv file :
推荐答案
这是您的代码的简化版本:
Here's a streamlined version of your code:
$CSVpath = "G:\1.csv"
$xmlPath = "G:\1.xml"
# This is a more robust (and faster) way to load XML files.
($xmlDoc = [xml]::new()).Load((Convert-Path $xmlPath))
# Get all column names
$columnNames = (Get-Content -First 1 $CSVpath) -split ',' -replace '"'
Write-Host "Column count: $($columnNames.Count); names: $columnNames"
foreach ($columnName in $columnNames) {
@($xmlDoc.enum_types.enum_type.Where({ $_.field_name -eq $columnName }, 'First').
items).ForEach({ $_.item }).Where({ $_.id -eq 1 }).value
}
它为我输出以下内容:
Column count: 2; names: Test1 Test2
A
A
注意:
由于您的 XML 文档中没有 CDATA 部分,因此不需要
.'#cdata-section'
使用 .ForEach()
来枚举名为
的子元素的基本原理,特别是 - 虽然对于您的示例 XML 文档并不是绝对必要的,因为只有一个这样的子元素 - 在这个答案中进行了解释.
The rationale for using .ForEach()
to enumerate the child elements named <item>
, specifically - while not strictly necessary with your sample XML document, since there's only one such child element - is explained in this answer.
@(...)
的使用,array-subexpression operator,以便应用.ForEach()
(和.Where()
) 安全仅在 Windows PowerShell 中是必需的,这是由于一个不幸的错误[1],该错误已在 PowerShell (Core) 7+ 中得到修复.
Use of
@(...)
, the array-subexpression operator, in order to apply.ForEach()
(and.Where()
) safely is only required in Windows PowerShell, due to an unfortunate bug[1], which has since been fixed in PowerShell (Core) 7+.
链接的答案还显示了一个更快的基于 XPath 的解决方案,通过 Select-Xml
,您可以类似地将其应用于内存中已经存在的 [xml]
实例 ($xmlDoc
在这种情况下),通过其 .SelectSingleNode()
实例方法.
The linked answer also shows a - faster - XPath-based solution, via Select-Xml
, which you could apply analogously to an [xml]
instance already in memory ($xmlDoc
in this case), via its .SelectSingleNode()
instance method.
以上仅对 CSV 文件的列名进行操作,带有 hard-coded id
值 - 就像您自己的尝试.
The above only operates on the column names of the CSV file, with a hard-coded id
value - as in your own attempt.
要根据 CSV 中的数据并根据填充的列从 XML 中提取数据:
To extract data from the XML based on the data in the CSV and based on which columns are filled in:
$CSVpath = "G:\1.csv"
$xmlPath = "G:\1.xml"
# This is a more robust (and faster) way to load XML files.
($xmlDoc = [xml]::new()).Load((Convert-Path $xmlPath))
# Import the CSV.
$csvRows = Import-Csv $CSVpath
# Get the column names.
$columnNames = $csvRows[0].psobject.Properties.Name
foreach ($csvRow in $csvRows) {
foreach ($columnName in $columnNames) {
$id = $csvRow.$columnName
if (-not $id) { continue }
@($xmlDoc.enum_types.enum_type.Where({ $_.field_name -eq $columnName }, 'First').
items).ForEach({ $_.item }).Where({ $_.id -eq $id }).value
}
}
注意:对于这样的嵌套循环,绝对值得考虑使用 .SelectSingleNode()
切换到 XPath 解决方案以提高性能.
Note: With a nested loop like that it's definitely worth considering switching to an XPath solution with .SelectSingleNode()
in order to improve performance.
[1] .ForEach()
和 .Where()
应该适用于任何对象,甚至标量(非集合),但在 Windows PowerShell 中无法处理某些类型,例如 XML 元素.
[1] .ForEach()
and .Where()
should work on any object, even scalar (non-collection) ones, but in Windows PowerShell that doesn't work with certain types, such as XML elements.
这篇关于如何使用 csv 列标题 powershell 获取 xml 字段值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!