我正在尝试根据客户发送给我们的xml文件自动创建销售订单。
他们的XML文件的结构在不同的客户之间有所不同,因此我创建了一个SQL Server表,其中包含每个客户的基本订单信息路径。
$salesOrder
包含整个XML文件。
将SQL数据加载到$customerTemplate
中,并将订单行加载到名为$SalesOrderLines
的数组中:
$salesOrderLines = @($salesOrder.SelectNodes($customerTemplate.LinePath))
问题是当我遍历订单行数组时,例如:
foreach ($salesOrderLine in $salesOrderLines) {
$partCode = ($salesOrderLine.SelectSingleNode($customerTemplate.PartCodePath)).'#text'
}
它对于第一个订单行工作正常,即它选择了正确的零件代码,但对于任何后续订单行$partCode
保持相同的值。即使我在循环结束时清除了$partCode
变量,当它拾取第二个订单行时,$partCode
也会从第一个订单行中获取值-尽管我可以看到$ orderLine包含正确的我正在寻找的属性。
我是否错过了一些明显的事情,因为在尝试解决此问题两天后,我没有取得太大进展吗?我可以根据需要提供整个脚本,但是我认为要求所有人检查300行代码实在太大了。
带有单个订单行的XML示例:
<?xml version="1.0"?>
<eExact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="eExact-Schema.xsd">
<Orders>
<Order type="B" number="23298">
<OrderedAt>
<Creditor code="100001" number="100001" type="S">
<Name>Widget Co</Name>
<ExternalCode>EW001</ExternalCode>
</Creditor>
<Date>2018-01-31</Date>
</OrderedAt>
<OrderLine lineNo="1">
<Description>Widget Sub Assy Std</Description>
<Item code="12345" type="S" searchcode="">
<Description>Widget Sub Assy Std</Description>
</Item>
<Quantity>1</Quantity>
<ItemCode>12345</ItemCode>
</OrderLine>
</Order>
</Orders>
</eExact>
这是一个重现该问题的代码示例:
[xml]$salesOrder = Get-Content -Path "C:\Temp\PurchaseOrder.xml"
$salesOrderLines = @($salesOrder.SelectNodes("/eExact/Orders/Order/OrderLine"))
foreach ($salesOrderLine in $salesOrderLines) {
$partCode = ($salesOrderLine.SelectSingleNode("//ItemCode")).'#text'
$orderQty = ($salesOrderLine.SelectSingleNode("//Quantity")).'#text'
$salesOrderLine.InnerXml
"Part code = $partCode, Qty = $orderQty"
Clear-Variable partCode, orderQty
}
以2行顺序显示,输出为:
<Description>Widget Sub Assy Std</Description><Item code="12345" type="S" searchcode=""><Description>Widget Sub Assy Std</Description></Item><Quantity>1</Quantity><ItemCode>12345</ItemCode>
Part code = 12345, Qty = 1
<Description>Big Widget</Description><Item code="54321" type="S" searchcode=""><Description>Big Widget</Description></Item><Quantity>3</Quantity><ItemCode>54321</ItemCode>
Part code = 12345, Qty = 1
有了更多的订单行,我得到的第一零件编号和数量相同的重复次数更多。 我希望第二个订单行的输出是:
Part code = 54321, Qty = 3
答案 0 :(得分:1)
用于选择<ItemCode>
和<Quantity>
节点的XPath表达式不正确。您正在正确的父节点上调用SelectSingleNode()
,但是表达式不是相对于该节点的。 //
表示根节点下方的任何位置,因此您始终选择XML文档中的第一个<ItemCode>
和<Quantity>
节点。
使表达式相对于当前节点(对于直接子节点为./
,对于当前节点的任何后代为.//
),代码将执行您想要的操作。另外,之后无需清除变量,因此只需删除Clear-Variable
语句即可。也要删除分组括号。无需PowerShell代码看起来就像别人割指甲一样。
foreach ($salesOrderLine in $salesOrderLines) {
$partCode = $salesOrderLine.SelectSingleNode('./ItemCode').'#text'
$orderQty = $salesOrderLine.SelectSingleNode('./Quantity').'#text'
"Part code = ${partCode}`nQty = ${orderQty}"
}