Product: Mapping Manager
Article Link: http://help.truecommerce.com/en/articles/10002618-xpath-predicate-selection-by-instance-ordering
Often when writing an xPath you may need to filter the results of your selection down to a specific result based on its order in the XML (sometimes called an instance). Whether you need to select the first, second, or last element.
You can do this by utilizing either a static selector or by calling one of the handy functions that exist to check against a particular order.
Example XML
In this example we have an Advance Ship Notice (856) that is formatted in the SOPI (Shipment, Order, Pack, Item) structure.
<EDI856>
<Shipment>
<ShipmentID>SHIP12345</ShipmentID>
<ShipmentDate>2024-10-16</ShipmentDate>
<Carrier>FedEx</Carrier>
<Order>
<OrderID>ORD98765</OrderID>
<CustomerID>CUST123</CustomerID>
<Pack>
<PackID>PKG001</PackID>
<UCC>123456789012345678</UCC>
<Item>
<ItemID>ITEM001</ItemID>
<Description>Widget A</Description>
<Quantity>10</Quantity>
</Item>
<Item>
<ItemID>ITEM002</ItemID>
<Description>Widget B</Description>
<Quantity>5</Quantity>
</Item>
</Pack>
<Pack>
<PackID>PKG002</PackID>
<UCC>123456789012345679</UCC>
<Item>
<ItemID>ITEM003</ItemID>
<Description>Widget C</Description>
<Quantity>3</Quantity>
</Item>
</Pack>
<Pack>
<PackID>PKG003</PackID>
<UCC>123456789012345680</UCC>
<Item>
<ItemID>ITEM001</ItemID>
<Description>Widget A</Description>
<Quantity>7</Quantity>
</Item>
</Pack>
</Order>
</Shipment>
</EDI856>
Selecting by Ordering
You can select a particular element based on its placement relative to its other siblings utilizing the Instance Selection predicate. Defining which specific element you want is useful for limiting results, as well as grabbing something from a specific spot.
You can use predicate brackets [ ] to define which instance you would like to select.
Node[X]
(Where X equals the selection)
Note: Instance-Selection uses 1-based indexing
Selecting Based on Index
Often when you write an xPath you may return multiple results - however to write the value to a field, Transaction Manager needs to have only a single value returned in order to properly write.
You can do this by hard-coding a static number such as [1] or [5] to select that specific number.
Selecting 1st Pallet's UCC
Let's say your Advance Ship Notice (856) has multiple UCC-128s on it. You need to pull the Master Tracking number, but it's not defined on the XML in its own spot. You know that the first Pack always contains the master UCC-128 on it. You can select it, by hard-coding a [1] to your predicate.
Pack[1]/UCC
<Pack>
<PackID>PKG001</PackID>
<UCC>123456789012345678</UCC>
</Pack>
In this case your results would be : 123456789012345678 because it grabbed the 1st Package's UCC only.
Selecting the 2nd Item of the 1st Package
Perhaps you need to select the 2nd item within the 1st package specifically? Well you can do so by first selecting the 1st package, and then by selecting the 2nd item of that package.
Pack[1]/Item[2]
<Item>
<ItemID>ITEM002</ItemID>
<Description>Widget B</Description>
<Quantity>5</Quantity>
</Item>
By hard-coding the instance we wish to use and combining our pathing operators we can create a unique path to access specific data based on order
Selecting the Last Package
If we wish to select the very last package in an unknown amount of packages, we can do so by using the last() predicate.
Pack[last()]
<Pack>
<PackID>PKG003</PackID>
<UCC>123456789012345680</UCC>
<Item>
<ItemID>ITEM001</ItemID>
<Description>Widget A</Description>
<Quantity>7</Quantity>
</Item>
</Pack>
This returns the last package, regardless of how many are in the Shipment.
Selecting Even & Odd Packages
In addition to hard-coding the instance, you can check whether or not the Node is Even or Even by utilizing the position() function which allows us to compare its position, along with the mod function to determine if the function is odd or even.
Odd Items
Item[position() mod 2 = 1]
Even Items
Item[position() mod 2 = 0]
10/16/2024