You need to sign in to do that
Don't have an account?
Tony Williams 9
Traversing XML Trees using Apex
HI I'm trying top traverse an XML tree to get the Items Tag list. I was using iterative but the problem is that it seems that I can only get the lst item but I don;t get them all. Can someone p0leaswe help me? Thanks Here's the tree:
<Shipment id="103052074"> <ClientName>Awana</ClientName> <OrderID>01061767</OrderID> <PurchaseOrder /> <Name>SILVIA GIBSON</Name> <FirstName>SILVIA</FirstName> <LastName>GIBSON</LastName> <Company /> <Address1>11900 TRADITION LN NE </Address1> <Address2 /> <City>ALBUQUERQUE</City> <State>NM</State> <PostalCode>87111-8287</PostalCode> <Country>UNITED STATES</Country> <Email>silviagibson@mailinator.com</Email> <Phone /> <OrderTimestamp>2019-01-18T00:00:00</OrderTimestamp> <ReceivedTimestamp>2019-01-18T13:59:26.007</ReceivedTimestamp> <ShipmentStatus>SHIPPED</ShipmentStatus> <OrderType>Consumer</OrderType> <ShippedDate>2019-01-18T14:16:37.550</ShippedDate> <ExpectedDeliveryDate>2019-01-18T00:00:00</ExpectedDeliveryDate> <DeliveredTimestamp /> <DeliveryException /> <Warehouse id="160"> <Name>Greenwood, IN</Name> <Address>1415 Collins Rd.</Address> <City>Greenwood</City> <State>IN</State> <PostalCode>46143</PostalCode> <Country>US</Country> </Warehouse> <ShipMethod>Newgistics Parcel Select</ShipMethod> <ShipMethodCode>NGSPS</ShipMethodCode> <Tracking>9200000000000629213249</Tracking> <TrackingUrl>http://shipment.co/tracking/2817/9200000000000629213249</TrackingUrl> <Weight>4.000000</Weight> <Postage /> <GiftWrap>false</GiftWrap> <CustomFields> <BillingAddress1>1620 N Penny Ln</BillingAddress1> <BillingCity>Schaumburg</BillingCity> <BillingCompany>Cherry Hills Community Church</BillingCompany> <BillingCountry>United States</BillingCountry> <BillingEmail>silviagibson@mailinator.com</BillingEmail> <BillingFirstName>Heather</BillingFirstName> <BillingLastName>Oliver</BillingLastName> <BillingPhone>(866) 292-6227</BillingPhone> <BillingState>IL</BillingState> <BillingZip>60173</BillingZip> <Shipping>17.87</Shipping> <Total>190.52</Total> </CustomFields> <BackorderedItems /> <Items> <Item id="1807577"> <SKU>94900</SKU> <UPC /> <Description>Cubbies AppleSeed Handbook Music CD NIV</Description> <Lot /> <Qty>2</Qty> <CustomFields /> <AssemblyItems /> </Item> <Item id="1807606"> <SKU>96543</SKU> <UPC /> <Description>Cubbies HoneyComb Teaching Plans NKJV</Description> <Lot /> <Qty>1</Qty> <CustomFields /> <AssemblyItems /> </Item> <Item id="1807670"> <SKU>96918</SKU> <UPC /> <Description>Game Pin (4)</Description> <Lot /> <Qty>4</Qty> <CustomFields /> <AssemblyItems /> </Item> <Item id="1807691"> <SKU>46421</SKU> <UPC /> <Description>Gray Blouse, Leader Size 4X</Description> <Lot /> <Qty>3</Qty> <CustomFields /> <AssemblyItems /> </Item> </Items> <Packages> <Package id="86892375"> <TrackingNumber>9200000000000629213249</TrackingNumber> <Weight>4.30507</Weight> <BillableWeight>4.00000</BillableWeight> <Height>7.00000</Height> <Width>4.00000</Width> <Depth>6.00000</Depth> </Package> </Shipment>
You just want the <items> <Item id="1807577"> ... </item> </items>
There is a mistake in your xml source
<Packages>If you just install this class you can use a subset of XPath: https://github.com/JenniferSimonds/apex-xpath/blob/1.0.1/XPath.cls
https://github.com/JenniferSimonds/apex-xpath
Dom.XmlNode[] items = xp.find('/Shipment/Items/Item');
You just need this XPath expression : /Shipment/Items/Item ( shortest way to get all the items )
All Answers
You just want the <items> <Item id="1807577"> ... </item> </items>
There is a mistake in your xml source
<Packages>If you just install this class you can use a subset of XPath: https://github.com/JenniferSimonds/apex-xpath/blob/1.0.1/XPath.cls
https://github.com/JenniferSimonds/apex-xpath
Dom.XmlNode[] items = xp.find('/Shipment/Items/Item');
You just need this XPath expression : /Shipment/Items/Item ( shortest way to get all the items )
.
You can get the items directly with just one short XPath expression.
I am using a lot XQuery and my favorite tool is BaseX (German tool in java) but that is not possible in Apex.
We never use the recursive solution as far as possible because it is far too verbose.
I got the four items without problem.
The other problem with the recursive method is to verify the relative position all the time (parent).
By the way there is an error here:
if(node.getName() == 'Items' &&
node.getParent().getParent().getName() == 'Shipment'){XPath expression : /Shipment/Items/Item ( the parent of items is direct )
It is a common error whitout using XPath.
if(node.getName() == 'Items' && node.getParent().getName() == 'Shipment'){
... should be sufficient.
You have two loops for the recursions but that is not the problem anymore given that there is an error for the first loop.
I tried the XPath alternative and that works for me.
All the needed code is below (don't parse with doc.load() anymore). What is your XML text now?
Just copy/paste the code below in an anonymous window of a free developer org. I keep all these working samples because that could be usefull for my own work later.
Hello
Digging this old one as the solution is very clean and elegant. It works great in the examples and when I duplicate the actual response into a manual string but seems to break when used on an actual SOAP RS.
The issue seems to be from the second line below:
What do we need to do to convert the response output into a readable format for the XPath util?
Thanks