未能检索到正确的节点数据
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}"
}
我正在尝试根据客户发送给我们的 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}"
}