Problem reading nodes

davearia

Well-known member
Joined
Jan 4, 2005
Messages
184
Hi,

Here is my xml:
Code:
<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:
Code:
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.
 
And why dont you use the order you want to use ( orderXmlItem )?
You always use the rootnode ( order) !
 
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 cant 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:
Code:
<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, its more syntactically correct to use simply "Product", as in:
Code:
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
 
Not real sure why all for for each loops youre 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.
Code:
        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?
 
One other thing... just a suggestion, but instead of doing this big sub call
Code:
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...
Code:
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. :)
 
Makes a lot of sense I will take this on board tomorrow when I rewrite this part again.

Thank, Dave.
 
Back
Top