title: Amazon Marketplace XML parsing with LINQ
body: <p>I have a series of complicated XML files from Amazon showing order reports. </p>
  
  <p>A XML snippet is as follow:</p>
  
  <pre><code>&lt;Order&gt;
    &lt;AmazonOrderID&gt;000-1111111-2222222&lt;/AmazonOrderID&gt;
    &lt;MerchantOrderID&gt;111-3333333-4444444&lt;/MerchantOrderID&gt;
    &lt;PurchaseDate&gt;2012-03-02T13:28:53+00:00&lt;/PurchaseDate&gt;
    &lt;LastUpdatedDate&gt;2012-03-02T13:29:05+00:00&lt;/LastUpdatedDate&gt;
    &lt;OrderStatus&gt;Pending&lt;/OrderStatus&gt;
    &lt;SalesChannel&gt;Amazon.com&lt;/SalesChannel&gt;
    &lt;URL&gt;http://www.amazon.com&lt;/URL&gt;
    &lt;FulfillmentData&gt;
      &lt;FulfillmentChannel&gt;Amazon&lt;/FulfillmentChannel&gt;
      &lt;ShipServiceLevel&gt;Standard&lt;/ShipServiceLevel&gt;
      &lt;Address&gt;
        &lt;City&gt;Beverly Hills&lt;/City&gt;
        &lt;State&gt;CA&lt;/State&gt;
        &lt;PostalCode&gt;90210-1234&lt;/PostalCode&gt;
        &lt;Country&gt;US&lt;/Country&gt;
      &lt;/Address&gt;
    &lt;/FulfillmentData&gt;
    &lt;OrderItem&gt;
      &lt;ASIN&gt;AmazonASIN &lt;/ASIN&gt;
      &lt;SKU&gt; Internal-SKU&lt;/SKU&gt;
      &lt;ItemStatus&gt;Pending&lt;/ItemStatus&gt;
      &lt;ProductName&gt; This is the name of the product &lt;/ProductName&gt;
      &lt;Quantity&gt;1&lt;/Quantity&gt;
      &lt;ItemPrice&gt;
        &lt;Component&gt;
          &lt;Type&gt;Principal&lt;/Type&gt;
          &lt;Amount currency="USD"&gt;19.99&lt;/Amount&gt;
        &lt;/Component&gt;
      &lt;/ItemPrice&gt;
    &lt;/OrderItem&gt;
  &lt;/Order&gt;
  </code></pre>
  
  <p>What I need to do with this file is extract various parts of the XML document and then do a number of things with the data. </p>
  
  <p>The problem I am having comes with multiple order items. </p>
  
  <p>The following code will correctly grab each node and put it into a list item, however I am unsure how to associate those multiple items with the same order number within C#. </p>
  
  <p>C# snippet: </p>
  
  <pre><code>List&lt;string&gt; getNodes(string path, string nodeName) {
  
      List&lt;string&gt; nodes = new List&lt;string&gt;(); 
  
      XDocument xmlDoc = XDocument.Load(path); //Create the XML document type
  
      foreach (var el in xmlDoc.Descendants(nodeName)) {
              //for debugging
              //nodes.Add(el.Name + " " + el.Value);
  
              //for production
              nodes.Add(el.Value);
      }
     return nodes;
  } //end getNodes
  </code></pre>
  
  <p>The method is called like: </p>
  
  <pre><code>List&lt;string&gt; skuNodes = xml.getNodes(@"AmazonSalesOrders.xml", "SKU");
  </code></pre>
  
  <p>where xml is the instantiated class. </p>
  
  <p>To further explain the complication: If each node is put into its own list the length of the list will be constant providing only one item is ordered. Once multiple items are ordered the SKU, quantity, price etc lists will become longer and prevent an easy loop. </p>
  
  <p>I am sure there is a LINQ to XML statement that can do what I need, but I am no where near experienced enough with C# to hack it out. </p>
  
  <p>+++++++++++++++ EDIT +++++++++++++++++++</p>
  
  <p>I'm trying some LINQ suggestions I have found around the web. The following looks promising but is returning exception: </p>
  
  <pre><code>base {System.SystemException} = {"Object reference not set to an instance of an object."}
  </code></pre>
  
  <p>code is: </p>
  
  <pre><code>var query = from xEle in xmlDoc.Descendants(node)
              where xEle.Element("AmazonOrderID").Value.ToString() == primaryKey
              select new {
                     tag = xEle.Name.LocalName,
                     value = xEle.Value
              };
  </code></pre>
  
  <p>I am unsure why this is occurring, the variables of node, and primary key are passed at runtime. </p>
  
  <p>If I set breakpoints, I can see that primaryKey is being passed correctly, same with node; however when I get to: </p>
  
  <pre><code>Dictionary&lt;string, string&gt; ordersByID = new Dictionary&lt;string, string&gt;();
  
          foreach (var CurNode in query) {
              ordersByID.Add(CurNode.tag, CurNode.value);
          }
  </code></pre>
  
  <p>I get the null reference error as it parses CurNode. </p>