tags:

views:

295

answers:

1

I need to simplify this xml ( to a list ), and associate the pricing with the items (multiple items)

here is my start, but the commented section does not work

            XDocument doc = XDocument.Load( filename );

            var ele = doc.Elements("AmazonEnvelope")
                            //.Elements("Header")
                            .Elements("Message")
                            .Elements("OrderReport")
                            .Elements("Item")

                              .Select(element => new
                              {
                                  AmazonOrderItemCode = (string)element.Element("AmazonOrderItemCode"),
                                  SKU = (string)element.Element("SKU"),
                                  Title = (string)element.Element("Title"),
                                  Quantity = (string)element.Element("Quantity"),

                              })

                             //.Elements("ItemPrice")
                             //.Elements("Component")

                              //.Select(element => new
                              //{
                             //     Type = (string)element.Element("Type"),
                             //     Amount = (string)element.Element("Amount"),
                             // })


                           .ToList();


            foreach (var x in ele)
            {
                Console.WriteLine(x.ToString());
            }

this: { AmazonOrderItemCode = 58317736573050, SKU = 6020B, Title = Top Coat, Quantity = 1 }

to this: { AmazonOrderItemCode = 58317736573050, SKU = 6020B, Title = Top Coat, Quantity = 1, Type = Principal, Amount = 8.00 }

and eventually, since there are multiple types, somthing like this:

{ AmazonOrderItemCode = 58317736573050, SKU = 6020B, Title = Top Coat, Quantity = 1, Amount_Principal = 8.00 }


Example XML (this is just 1 line item within the overall order)

<Item>
<AmazonOrderItemCode>23845287148226</AmazonOrderItemCode>
<SKU>557B</SKU>
<Title>China Doll</Title>
<Quantity>1</Quantity>
<ProductTaxCode>A_GEN_TAX</ProductTaxCode>
<ItemPrice>
<Component>
<Type>Principal</Type>
<Amount currency="USD">8.00</Amount>
</Component>
<Component>
<Type>Shipping</Type>
<Amount currency="USD">2.08</Amount>
</Component>
<Component>
<Type>Tax</Type>
<Amount currency="USD">0.68</Amount>
</Component>
<Component>
<Type>ShippingTax</Type>
<Amount currency="USD">0.17</Amount>
</Component>
</ItemPrice>
<ItemFees>
<Fee>
<Type>Commission</Type>
<Amount currency="USD">-1.51</Amount>
</Fee>
</ItemFees>
<ItemTaxData>
<TaxJurisdictions>
<TaxLocationCode>330812010</TaxLocationCode>
<City>QUEENS</City>
<County>QUEENS</County>
<State>NY</State>
</TaxJurisdictions>
<TaxableAmounts>
<District currency="USD">0.00</District>
<City currency="USD">8.00</City>
<County currency="USD">0.00</County>
<State currency="USD">8.00</State>
</TaxableAmounts>
<NonTaxableAmounts>
<District currency="USD">8.00</District>
<City currency="USD">0.00</City>
<County currency="USD">0.00</County>
<State currency="USD">0.00</State>
</NonTaxableAmounts>
<ZeroRatedAmounts>
<District currency="USD">0.00</District>
<City currency="USD">0.00</City>
<County currency="USD">8.00</County>
<State currency="USD">0.00</State>
</ZeroRatedAmounts>
<TaxCollectedAmounts>
<District currency="USD">0.00</District>
<City currency="USD">0.36</City>
<County currency="USD">0.00</County>
<State currency="USD">0.32</State>
</TaxCollectedAmounts>
<TaxRates>
<District>0.0000</District>
<City>0.0450</City>
<County>0.0000</County>
<State>0.0400</State>
</TaxRates>
</ItemTaxData>
<ShippingTaxData>
<TaxJurisdictions>
<TaxLocationCode>3308</TaxLocationCode>
<City>QUEENS</City>
<County>QUEENS</County>
<State>NY</State>
</TaxJurisdictions>
<TaxableAmounts>
<District currency="USD">0.00</District>
<City currency="USD">2.08</City>
<County currency="USD">0.00</County>
<State currency="USD">2.08</State>
</TaxableAmounts>
<NonTaxableAmounts>
<District currency="USD">2.08</District>
<City currency="USD">0.00</City>
<County currency="USD">0.00</County>
<State currency="USD">0.00</State>
</NonTaxableAmounts>
<ZeroRatedAmounts>
<District currency="USD">0.00</District>
<City currency="USD">0.00</City>
<County currency="USD">2.08</County>
<State currency="USD">0.00</State>
</ZeroRatedAmounts>
<TaxCollectedAmounts>
<District currency="USD">0.00</District>
<City currency="USD">0.09</City>
<County currency="USD">0.00</County>
<State currency="USD">0.08</State>
</TaxCollectedAmounts>
<TaxRates>
<District>0.0000</District>
<City>0.0450</City>
<County>0.0000</County>
<State>0.0400</State>
</TaxRates>
</ShippingTaxData>
</Item>
+1  A: 

Perhaps use two levels of anonymous select -- first get the Elements you need to use later, then grab the info out of each one to the real value you want to end up with.

var ele = doc.Elements("AmazonEnvelope")    
             .Elements("Message")   
             .Elements("OrderReport") 
             .Elements( "Item" )
             .Select( s => new
              {
                   AmazonOrderItemCode =
                        (string)s.Element( "AmazonOrderItemCode" ),
                   SKU = (string)s.Element( "SKU" ),
                   Title = (string)s.Element( "Title" ),
                   Quantity = (string)s.Element( "Quantity" ),
                   Type = (string)s.Element("ItemPrice")
                                   .Element("Component")
                                   .Element( "Type" ),
                   Amount = (string)s.Element( "ItemPrice" )
                                     .Element( "Component" )
                                     .Element( "Amount" )
              } )
             .ToList();
tvanfosson
it doesnt like .Element --> Component = e.Elements("ItemPrice").Element("Component")
Scott Kramer
Maybe try `e.Element("ItemPrice").Element("Component")` or even just `e.Element("Component")`? I don't do a lot of LINQ to XML. Basically the idea is to find that node and assign it temporarily so you can use it and the Item node together later. Let me know if either works and I'll update my answer.
tvanfosson
I tried a few things... doesnt want to work
Scott Kramer
Can you post some sample XML? I'll have a go at putting some code together.
tvanfosson
@Scott -- Based on your sample XML, I've updated. It wasn't clear to me from your original that ItemPrice is a child of Item. See if this works for you. the change is to select the Items elements, then for each one select the elements you need (as strings) and then from it's grandchild Component element the additional elements. From that you can build the anonymous type that flattens the structure as desired.
tvanfosson
looks good, since there are multiple type/amounts, do you know how to get to each one? this only does the first-- I'll experiment a little, thanks!
Scott Kramer
`Type = string.Join( ",", Element("Component").Elements("Type").Select( t => t.ToString() ).ToArray() )`
tvanfosson
tried this: Type = string.Join(",", s.Element("ItemPrice").Element("Component").Elements("Type").Select(t => t.ToString()).ToArray())however gives this... , Type = <Type>Principal</Type>, Amount = <Amount currency="USD">8.00</Amount> }look like it breaks out currency="USD"
Scott Kramer
So you probably need to get the Value of the node rather than just use ToString() -- I assumed it would work the same way as casting to a string.
tvanfosson