powershell - 将大型 XML 文件解析为 PowerShell 对象

标签 powershell xml-parsing

我是 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/

相关文章:

java - 当找不到 @XmlIDREF ref 时,Jaxb 不会抛出异常

python - Youtube-dl 订阅 mp3

powershell - 处理来自PowerShell脚本的DISM错误

sql-server - 如何获取数据集中表的特定列?

powershell - 命令提示符 : access denied when run PowerShell

java - Cygwin 运行的 java 版本与 windows powershell 不同

java - 使用 SAX 解析器修改 xml 文件

ios - 如何解析响应标记内包含 XML 文档的 SOAP 响应

xml - phobos 的 std.xml 的状态是什么

json - 如何使用powershell为aws格式化json字符串