使用PowerShell

时间:2018-06-08 15:11:25

标签: xml powershell

我一直在编写一个脚本来解析xml文档,以便找到文件中特定部分的任何重复项。对于上下文,这是XML文档在通过导入过程之前经历的预处理的一部分。

我能够缩小导致导入过程失败的特定部分:

        <OrderLineAct IsEmpty="N" Imported="Y" RecordID="" Error="" Version="15.4.0.3" OrderNumber="21-000138765">
            <Code>RR</Code>
            <CodeType>POSITION</CodeType>
            <JobCodeID>0</JobCodeID>
            <JobsFltID>0</JobsFltID>
            <LineID>16348542</LineID>
            <Modified>6/6/2018 8:50:00 AM</Modified>
            <ModifiedBy>JANETC</ModifiedBy>
            <OrderID>2294006</OrderID>
            <Qty>0</Qty>
            <QtyUOM></QtyUOM>
            <Section>3863523</Section>
        </OrderLineAct>
        <OrderLineAct IsEmpty="N" Imported="N" RecordID="" Error="" Version="15.4.0.3">
            <Code>RR</Code>
            <CodeType>POSITION</CodeType>
            <JobCodeID>0</JobCodeID>
            <JobsFltID>0</JobsFltID>
            <LineID>16348542</LineID>
            <Modified>6/6/2018 8:50:00 AM</Modified>
            <ModifiedBy>JANETC</ModifiedBy>
            <OrderID>2294006</OrderID>
            <Qty>0</Qty>
            <QtyUOM></QtyUOM>
            <Section>3863523</Section>
        </OrderLineAct> 

拥有此重复部分会导致文件在导入器内部经历无限循环,从而导致文件无法完成导入过程。

我需要做的是确定这些OrderLineActs中的任何一个是否与其父节点中的现有一个相同。这些OrderLineActs中的每一个都位于OrderLine段内。

我很难思考如何实现这一目标。我的第一个想法是通过并删除包含Imported="N"的任何内容,但如果另一个OrderLineAct由于某种原因导致导入失败,则可能会遇到问题。

我的想法是将其结构类似于我如何完全删除XML中的另一个标记:

Function Remove-UnitMeter
{
    param($xml)

    # strip the xml of any UnitMeter tags - done for every schema
    foreach($VendorInvoice in $xml.VendorInvoices)
    {
        foreach($Order in $VendorInvoice.Order)
        {
            # remove the UnitMeter tag from the XML file
            if ($Order.UnitMeter -ne $null){
                $Order.RemoveChild($Order.UnitMeter) | Out-Null # out-null otherwise it'll output all of the tags
            }
        } # end order
    } # end vendorinvoice

    return $xml
}

我知道我必须将孩子从父母身上移走,但我需要能够在我做之前确定它是否真的重复。

以前有没有人做过这样的事情?我可以根据需要提供更多信息。感谢。

1 个答案:

答案 0 :(得分:0)

猜猜我所要做的就是走开一段时间,因为我想出来了。

#[xml]$xml = Get-Content "\\papertransport.com\files\UserDocuments\mneis\Code\XML\TMT XML Files\PTIInvoices_Exporting.18-06-11 03.31.13.xml"
[xml]$xml = Get-Content "\\pedi01\masgre\FTPTransfer.Received\EXCP_20180329042048.xml"

foreach($VendorInvoice in $xml.VendorInvoices)
{
    foreach($Order in $VendorInvoice.Order)
    {
        foreach($OrderSec in $Order.OrderSec)
        {
            foreach($OrderLine in $OrderSec.OrderLine)
            {
                # store the acts inside a node object (from the orderline object) because you need to get all of them
                # but only select the Code and CodeType
                if ($OrderLine.OrderLineAct -ne $null){
                    $OrderLineActs = $OrderLine.OrderLineAct | Select -Property Code, CodeType

                    # find the duplicate
                    foreach($OrderLineAct in $OrderLineActs)
                    {
                        if ($OrderLine.OrderLineAct -ne $null)
                        {
                            # select the uniques
                            $Unique = $OrderLineActs | Select * -Unique

                            # compare the two objects to find the duplicate - the duplicate will have a SideIndicator of <=
                            $ComparedObjects = Compare-Object -ReferenceObject $OrderLineActs `
                                                              -DifferenceObject $Unique `
                                                              -IncludeEqual
                            $Duplicate = $ComparedObjects | Where {$_.SideIndicator -eq '<='}
                        }
                    } 

                    if ($Duplicate -ne $null){
                        $DuplicateAct = $OrderLine.OrderLineAct | Where {($_.Code -eq $Duplicate.InputObject.Code) -and ($_.CodeType -eq $Duplicate.InputObject.CodeType)}
                        $DuplicateAct = $DuplicateAct | Select -Last 1
                        Write-Host '-------------------Deleted-------------------'
                        $OrderLine.RemoveChild($DuplicateAct)
                    }
                }
            } # orderline
        } # ordersec
    } # order
} # vendor invoice

$xml.OuterXml | Out-file "C:\MyFiles\Temp\RemoveAct.xml"

可能不是那里最漂亮的解决方案,但它做了我需要它做的事情。 基本上我所做的是创建一个包含我想要比较的所有东西的对象,然后过滤并缩小重复项,然后从父项中删除该部分。如果其他人有更好的解决方案,请告诉我们!