Удалить дублирующийся раздел XML с помощью PowerShell - PullRequest
0 голосов
/ 08 июня 2018

Я работал над сценарием для анализа 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 голосов
/ 11 июня 2018

Думаю, все, что мне нужно сделать, это уйти на некоторое время, потому что я понял это.

#[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"

Возможно, это не самое симпатичное решение, но оно делает то, что мне нужно.По сути, я создаю объект, содержащий все, что я хочу сравнить, затем фильтрую и сужаю дубликаты, а затем удаляю раздел из родительского объекта.Если у кого-то есть лучшее решение, пожалуйста, дайте мне знать!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...