我是 PowerShell 和 XPath 初学者,正在努力有效地解析一些 XML 并构建一组对象以进行进一步处理(例如 CSV 输出、SQL Server 加载)。下面包含一个 XML 示例以及我当前使用的代码片段。在这个模式中,每个 object-array
表示所需输出中的单行。我正在解析 MetaData
children 获取列的正确名称,然后构建 PSObjects 的集合,其中数组中的每个对象代表一行。 MetaData
信息用于查找列名(PSObject 属性)。
这适用于具有 10K 行左右的文件,但在针对我的超过 500K 行的最大文件运行时会陷入可怕的困境。在这些情况下,每一行大约需要 3-4 秒来处理。在 500K 行时,这是一个很长的运行时间。我可以用 XPath 或 PS 变量赋值来加快速度吗?
立即需要将此 XML 转换为 CSV(当前通过 export-csv
执行),但我更愿意让脚本的这一部分生成一组对象,因为接下来我将寻求将此数据加载到SQL Server 实例或进行其他处理。
谢谢您的帮助!
大卫
示例 XML
<Report>
<Data>
<Columns>
<MetaData>
<Index>0</Index>
<Name>Column1</Name>
<Index>1</Index>
<Name>Column2</Name>
<Index>2</Index>
<Name>Column3</Name>
</MetaData>
</Columns>
<Rows>
<object-array>
<string>column1 value</string>
<int>column2 value</string>
<string>column3 value</string>
</object-array>
</Rows>
</Data>
</Report>
示例代码
#extract the column headers
[string[]]$ColumnHeaders = @()
$obj.SelectNodes("/Report/Data/Columns/MetaData") |% {$ColumnHeaders += $_.name}
$collection = @()
$rowint = 0
$rowcount = $obj.Report.Data.Rows."object-array".count
#unwind the rows
do {
$hash=@{}
#loop through each element in the row parent element and add it to the hash
$columnint = 0
$columncount = (Select-Xml -xPath "Report/Data/Rows/object-array[$rowint]/node()" $obj).count
do {
$hash.Add($columnheaders[$columnint], (Select-Xml -xPath "Report/Data/Rows/object-array[$rowint]/descendant::text()[$columnint]" $obj).Node.Value)
$columnint++
} while ($columnint -lt $columncount)
$thisrow = New-Object PSObject -Property $hash
#add this new row to the collection
$collection += $thisrow
$rowint++
} while ($rowint -lt $rowcount)
最佳答案
您无需在每次迭代中重新创建 ColumnHeaders 即可获取 MetaData 名称:
$ColumnHeaders = $obj.Report.Data.Columns.MetaData.Name
同样适用于 $collection。您的代码的最终结果如何?
更新:试试这个
[xml]$obj = Get-Content test.xml
$data = $obj.Report.Data
$pso = New-Object PSObject
$pso | Add-Member NoteProperty -Name $data.Columns.MetaData.Name[0] -Value $data.Rows.'object-array'.string[0]
$pso | Add-Member NoteProperty -Name $data.Columns.MetaData.Name[1] -Value $data.Rows.'object-array'.int
$pso | Add-Member NoteProperty -Name $data.Columns.MetaData.Name[2] -Value $data.Rows.'object-array'.string[1] -PassThru
关于powershell - 将大型 XML 文件解析为 PowerShell 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11492145/