我一直在编写一个脚本来解析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
}
我知道我必须将孩子从父母身上移走,但我需要能够在我做之前确定它是否真的重复。
以前有没有人做过这样的事情?我可以根据需要提供更多信息。感谢。
答案 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"
可能不是那里最漂亮的解决方案,但它做了我需要它做的事情。 基本上我所做的是创建一个包含我想要比较的所有东西的对象,然后过滤并缩小重复项,然后从父项中删除该部分。如果其他人有更好的解决方案,请告诉我们!