davearia Posted November 9, 2006 Posted November 9, 2006 Hi, Here is my xml: <Orders> <Header> <CompanyGUID>026b518c-6916-434a-85ba-88fedce62fac</CompanyGUID> <API_Version>1</API_Version> </Header> <Order SONumber= "123456"> <OrderConfiguration> <StockStatus>Wait</StockStatus> <CanBeQueued>True</CanBeQueued> </OrderConfiguration> <Product> <QuickLinx>123YY</QuickLinx> <Quantity>4</Quantity> <Price>99.99</Price> </Product> <Address> <BusinessName>A made up name</BusinessName> <HouseNoAndStreetName>2 Made Up Street</HouseNoAndStreetName> <Town>Bolton</Town> <PostCode>BL11BL</PostCode> </Address> <Carriage> <CarriageType>4</CarriageType> </Carriage> </Order> <Order SONumber= "876543"> <OrderConfiguration> <StockStatus>Line</StockStatus> <CanBeQueued>False</CanBeQueued> </OrderConfiguration> <Product> <QuickLinx>122WW</QuickLinx> <Quantity>2</Quantity> <Price>9.99</Price> </Product> <Address> <BusinessName>Another made up name</BusinessName> <HouseNoAndStreetName>55 Made Up Street</HouseNoAndStreetName> <Town>Bolton</Town> <PostCode>BL22BL</PostCode> </Address> <Carriage> <CarriageType>3</CarriageType> </Carriage> </Order> <Order SONumber= "123789"> <OrderConfiguration> <StockStatus>Wait</StockStatus> <CanBeQueued>True</CanBeQueued> </OrderConfiguration> <Product> <QuickLinx>12WW</QuickLinx> <Quantity>66</Quantity> <Price>699.99</Price> </Product> <Address> <BusinessName>Another made up name</BusinessName> <HouseNoAndStreetName>233 Made Up Street</HouseNoAndStreetName> <Town>Bolton</Town> <PostCode>BL55BL</PostCode> </Address> <Carriage> <CarriageType>32</CarriageType> </Carriage> </Order> </Orders> Here is the code that reads the XML: Dim ordersXMLNodelst As XmlNodeList = order.SelectNodes("//Orders") For Each ordersXMLItem As XmlNode In ordersXMLNodelst 'Order loop: Dim orderXMLNodelst As XmlNodeList = order.SelectNodes("//Order") For Each orderXMLItem As XmlNode In orderXMLNodelst If orderXMLItem.Attributes("SONumber") IsNot Nothing Then 'Create local variables to hold order details: 'Customers Sales order number Dim custSalesOrderNo As Int32 = Convert.ToInt32(orderXMLItem.Attributes("SONumber").InnerXml) 'Order configuration Dim stockStatus As String = String.Empty Dim canBeQueued As Boolean = True 'Product Dim QuickLinx As String = String.Empty Dim Quantity As Int32 = 0 Dim Price As Decimal = 0 'Address Dim BusinessName As String = String.Empty Dim HouseNoAndStreetName As String = String.Empty Dim Town As String = String.Empty Dim PostCode As String = String.Empty 'Carriage Dim CarriageType As Int32 = 0 'Build the individual order up: 'Get the order configuration Dim orderConfigurationXMLNodelst As XmlNodeList = order.SelectNodes("//OrderConfiguration") For Each orderConfigurationXMLItem As XmlNode In orderConfigurationXMLNodelst stockStatus = orderConfigurationXMLItem.SelectSingleNode("StockStatus").InnerXml() canBeQueued = Convert.ToBoolean(orderConfigurationXMLItem.SelectSingleNode("CanBeQueued").InnerXml()) Next 'Get the product information Dim productXMLNodelst As XmlNodeList = order.SelectNodes("//Product") For Each productXMLItem As XmlNode In productXMLNodelst QuickLinx = productXMLItem.SelectSingleNode("QuickLinx").InnerXml() Quantity = Convert.ToInt32(productXMLItem.SelectSingleNode("Quantity").InnerXml()) Price = Convert.ToDecimal(productXMLItem.SelectSingleNode("Price").InnerXml()) Next 'Get the address information Dim addressXMLNodelst As XmlNodeList = order.SelectNodes("//Address") For Each addressXMLItem As XmlNode In addressXMLNodelst BusinessName = addressXMLItem.SelectSingleNode("BusinessName").InnerXml() HouseNoAndStreetName = addressXMLItem.SelectSingleNode("HouseNoAndStreetName").InnerXml() Town = addressXMLItem.SelectSingleNode("Town").InnerXml() PostCode = addressXMLItem.SelectSingleNode("PostCode").InnerXml() Next 'Get the carriage information Dim carriageXMLNodelst As XmlNodeList = order.SelectNodes("//Carriage") For Each carriageXMLItem As XmlNode In carriageXMLNodelst CarriageType = Convert.ToInt32(carriageXMLItem.SelectSingleNode("CarriageType").InnerXml()) Next 'Call middle tier to place the order Dim middleTier As New MiddleTier Dim salesOrder As Int32 = 0 salesOrder = middleTier.placeOrder(stockStatus, canBeQueued, QuickLinx, Quantity, Price, BusinessName, HouseNoAndStreetName, Town, PostCode, CarriageType) Else orderDetails = "-1" End If Next Next What I am finding is that as I am iterating through the orders node looking at each order. When I get the values stored in the child nodes Product as an example. It seems to go through all of the Product nodes in all of the orders each time it loops through. What I wanted was to get the Product values belonging to its respective order. Does anyone know where I am going wrong? If so please help, cheers, Dave. Quote
FZelle Posted November 10, 2006 Posted November 10, 2006 And why don't you use the order you want to use ( orderXmlItem )? You always use the rootnode ( order) ! Quote
*Experts* Nerseus Posted November 10, 2006 *Experts* Posted November 10, 2006 Two problems, I think. 1. As mentioned, to get child nodes start by using the current node - orderXMLItem in your case, not order. 2. I can't recall how the child nodes work, but the "//" syntax is "select all from root", which MIGHT go back up to the real root, not the root of the current node. I may be wrong on that. You would only really need "//" if you had nested Product nodes, under an Order. For example: <Order> <Product id="1"> <Product ="2"> </Product> </Product> <Product id="3"> </Product> </Order> The "//" would select all 3 products. The SelectSingleNode would only pick up id="1". If you really wanted the first node, it's more syntactically correct to use simply "Product", as in: Dim productXMLNodelst As XmlNodeList = [b]orderXMLItem[/b].SelectNodes("Product") My whole 2nd point may not matter, depending on the how the SelectNodes works when called on a "child" node, such as my last sample using orderXMLItem above. -nerseus Quote "I want to stand as close to the edge as I can without going over. Out on the edge you see all the kinds of things you can't see from the center." - Kurt Vonnegut
Agent707 Posted November 10, 2006 Posted November 10, 2006 Not real sure why all for for each loops you're doing. You only need to loop through each "Order" it looks like. I just use a Node variable for each node inside your Order... Try something like this. Dim OrdersXMLRoot As XmlNode Dim OrderXMLChild As XmlNode Dim xmlNode As XmlNode OrdersXMLRoot = order.SelectSingleNode("Orders") For Each OrderXMLChild In OrdersXMLRoot.SelectNodes("Order") 'Get Order Number OrderNumber = OrderXMLChild.Attributes("SONumber").Value 'Order Configuration xmlNode = OrderXMLChild.SelectSingleNode("OrderConfiguration") StockStatus = xmlNode.SelectSingleNode("StockStatus").InnerText CanBeQueued = xmlNode.SelectSingleNode("CanBeQueued").InnerText 'Get product info xmlNode = OrderXMLChild.SelectSingleNode("Product") QuickLinx = xmlNode.SelectSingleNode("QuickLinx").InnerText Quantity = xmlNode.SelectSingleNode("Quantity").InnerText Price = xmlNode.SelectSingleNode("Price").InnerText 'Get Address info xmlNode = OrderXMLChild.SelectSingleNode("Address") BusinessName = xmlNode.SelectSingleNode("BusinessName").InnerText HouseNoAndStreetName = xmlNode.SelectSingleNode("HouseNoAndStreetName").InnerText Town = xmlNode.SelectSingleNode("Town").InnerText 'So forth and so on... Next What your doing here, is getting the node for each item (Configuration, Address, Product...etc.) and then getting the values from within each item of that node. Make sense? Quote
Agent707 Posted November 10, 2006 Posted November 10, 2006 One other thing... just a suggestion, but instead of doing this big sub call salesOrder = middleTier.placeOrder(stockStatus, canBeQueued, QuickLinx, Quantity, Price, BusinessName, HouseNoAndStreetName, Town, PostCode, CarriageType) Write a class and all these values you are grabbing in here and sticking in variables, set them into properties in your class, then when you have filled everything in... 'Same code above, except wrap around it... With YourClassName For Each 'Blah.... .OrderNumber = OrderXMLChild.Attributes("SONumber").Value .StockStatus = xmlNode.SelectSingleNode("StockStatus").InnerText 'etc. etc. 'place the order .PlaceOrder Next End With We do things very similar to this here. This type of code is very easy to maintain. Good luck. :) Quote
davearia Posted November 11, 2006 Author Posted November 11, 2006 Makes a lot of sense I will take this on board tomorrow when I rewrite this part again. Thank, Dave. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.