如何使用 csv 列 header powershell 获取 xml 字段值

How to get xml field value using csv column header powershell

当我使用 for 循环然后在代码 ({ $_.'field_name' -eq $b} 中添加值 $b 时,它会给出空白值结果。

$CSVpath = "G:.csv"
$columncount=((Get-Content $CSVpath)[0] -split ",").count
write-host $columncount
$xml= "G:.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:.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:

    <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 文件:

这是您的代码的简化版本:

$CSVpath = "G:.csv"
$xmlPath = "G:.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() 枚举名为 <item> 的子元素的基本原理,特别是 - 虽然您的样本 XML 文档并非绝对必要,因为只有one 这样的子元素 - 在 .

    中有解释
    • @(...)array-subexpression operator, in order to apply .ForEach()(和.Where())的安全使用仅在Windows PowerShell,由于一个不幸的错误[1],此错误已在 PowerShell (Core) 7+ 中修复。

    • 链接的答案还显示了一个更快的基于 XPath 的解决方案,通过 Select-Xml, which you could apply analogously to an [xml] instance already in memory ($xmlDoc in this case), via its .SelectSingleNode() 实例方法。


以上仅对 CSV 文件的 列名称 进行操作,具有 硬编码 id 值 -正如您自己的尝试。

根据CSV中的数据中提取数据XML,并根据哪些列填写 :

$CSVpath = "G:.csv"
$xmlPath = "G:.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 解决方案以提高性能。

[1] .ForEach().Where() 应该适用于 any 对象,甚至 scalar(非集合),但在 Windows PowerShell 中不适用于某些类型,例如 XML 元素。