未能检索到正确的节点数据

Failing to retrieve correct node data

我正在尝试根据客户发送给我们的 xml 文件自动创建销售订单。

他们的 XML 文件的结构因不同的客户而异,因此我创建了一个 SQL 服务器 table,其中包含每个客户的基本订单信息的路径。

$salesOrder 包含整个 XML 文件。 SQL 数据被加载到 $customerTemplate 中,订单行被加载到名为 $SalesOrderLines:

的数组中
$salesOrderLines = @($salesOrder.SelectNodes($customerTemplate.LinePath))

问题是当我遍历订单行数组时,例如:

foreach ($salesOrderLine in $salesOrderLines) {
    $partCode = ($salesOrderLine.SelectSingleNode($customerTemplate.PartCodePath)).'#text'
}

它对第一个订单行工作正常,即它选择了正确的零件代码,但对于任何后续订单行 $partCode 保持相同的值。即使我在循环结束时清除 $partCode 变量,当它拾取第二个订单行时 $partCode 从第一个订单行获取值 - 尽管我可以看到 $orderLine 包含正确的我正在寻找的属性。

我是不是错过了一些明显的东西,因为在尝试解决这个问题 2 天后我没有取得太大进展?如有必要,我可以提供整个脚本,但我认为要求任何人检查 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

您用于选择 <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}"
}