将两个 XML 与 PowerShell 匹配并减去第三个 XML?

Match two XML with PowerShell and result a subtracted third XML?

我想将文件 1 中的 powershell 脚本 supplierproductcode 与文件 2 进行匹配。当它找到匹配时,它应该创建具有相同信息的第三个文件,但从文件 2 中减去文件 1 中的数量。

文件 1

<stocklevelrecord>
    <supplierproductcode>1111</supplierproductcode>
    <quantity>100</quantity>
</stocklevelrecord>
<stocklevelrecord>
    <supplierproductcode>3333</supplierproductcode>
    <quantity>100</quantity>
</stocklevelrecord>

文件 2

<stocklevelrecord>
    <supplierproductcode>1111</supplierproductcode>
    <quantity>20</quantity>
</stocklevelrecord>
<stocklevelrecord>
    <supplierproductcode>2222</supplierproductcode>
    <quantity>30</quantity>
</stocklevelrecord>
<stocklevelrecord>
    <supplierproductcode>3333</supplierproductcode>
    <quantity>40</quantity>
</stocklevelrecord>
<stocklevelrecord>
    <supplierproductcode>4444</supplierproductcode>
    <quantity>50</quantity>
</stocklevelrecord>

结果文件

# quantity 100 (File 1) - quantity 20 (File 2)
<stocklevelrecord>
    <supplierproductcode>1111</supplierproductcode>
    <quantity>80</quantity>
</stocklevelrecord>
# quantity 100 (File 1) - quantity 40 (File 2)
<stocklevelrecord>
    <supplierproductcode>3333</supplierproductcode>
    <quantity>60</quantity>
</stocklevelrecord>

我是 PowerShell 的新手,需要指导。

一种简单的方法是遍历第一个文件中的记录,查找第二个文件中的代码,然后更新数量。

请注意,这最适合小文件。较大的文件(数百 KB 或 MB)可能受益于字典等索引,以避免将整个文档加载到内存中。

function Format-XML ([xml]$xml, $indent=2)
{
    # https://devblogs.microsoft.com/powershell/format-xml/
    $StringWriter = New-Object System.IO.StringWriter
    $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter
    $xmlWriter.Formatting = “indented”
    $xmlWriter.Indentation = $Indent
    $xml.WriteContentTo($XmlWriter)
    $XmlWriter.Flush()
    $StringWriter.Flush()
    Write-Output $StringWriter.ToString()
}

[xml] $file1 = "
<records>
    <stocklevelrecord>
        <supplierproductcode>1111</supplierproductcode>
        <quantity>100</quantity>
    </stocklevelrecord>
    <stocklevelrecord>
        <supplierproductcode>3333</supplierproductcode>
        <quantity>100</quantity>
    </stocklevelrecord>
</records>"

[xml] $file2 = "
<records>
    <stocklevelrecord>
        <supplierproductcode>1111</supplierproductcode>
        <quantity>20</quantity>
    </stocklevelrecord>
    <stocklevelrecord>
        <supplierproductcode>2222</supplierproductcode>
        <quantity>30</quantity>
    </stocklevelrecord>
    <stocklevelrecord>
        <supplierproductcode>3333</supplierproductcode>
        <quantity>40</quantity>
    </stocklevelrecord>
    <stocklevelrecord>
        <supplierproductcode>4444</supplierproductcode>
        <quantity>50</quantity>
    </stocklevelrecord>
</records>"

foreach ($file1Record in $file1.records.stocklevelrecord)
{
    $file1Code = $file1Record.supplierproductcode
    $file1Quantity = $file1Record.quantity

    foreach ($file2Record in $file2.records.stocklevelrecord)
    {
        $file2Code = $file2Record.supplierproductcode
        $file2Quantity = $file2Record.quantity

        if ($file1Code -eq $file2Code)
        {
            $file1Record.quantity = ($file1Quantity - $file2Quantity).ToString()
        }
    }
}

Clear-Host
Format-Xml $file1

# Output
#
# <records>
#   <stocklevelrecord>
#     <supplierproductcode>1111</supplierproductcode>
#     <quantity>80</quantity>
#   </stocklevelrecord>
#   <stocklevelrecord>
#     <supplierproductcode>3333</supplierproductcode>
#     <quantity>60</quantity>
#   </stocklevelrecord>
# </records>