2007
07.29

Amazon web services are one of the most feature and information-rich sources
of queryable product data available. They even have user and editorial reviews that
you can present to your customers to induce them to buy through your site. The
best part is that it’s free for developers (Get it at Amazon.com).
Here I want to present a short tutorial on how to access the data in AWS with
C#. It’s not really hard to use at all from .NET, and in fact is quite a bit
easier than some of the feeds I have dealt with before (e.g. Apple iTunes feed).
There are no namespaces in the nodes to worry about so our job is a bit simpler.

I know using XSLT might be preferable, but someone just might be looking for a
DOM-centric way to parse an XML feed.
In order to query the Amazon information database, you need an AWSAccessKeyId.
In order to get paid for any sales originating from your site, you need an
Amazon AssociateTag.
So the query URL would look something like this (substitute your AccessKeyId for
“12345” and your AssociateTag for “mytag-20”):

http://webservices.amazon.com/onca/xml?Service=AWSECommerceService
&AWSAccessKeyId=12345&AssociateTag=mytag-20

For this operation we will search for some items in a category (Mario VideoGames
in this case), so we append to the URL:
&Operation=ItemSearch&SearchIndex=VideoGames&Keywords=Mario

We also want to know about the items and get some prices and images so we tack
this on to the URL:
&ResponseGroup=Request,ItemAttributes,OfferSummary,Images

Lastly, we desire to see some reviews done by customers and editorial staff so
we append Reviews,EditorialReview

So the final URL looks like this:

http://webservices.amazon.com/onca/xml?Service=AWSECommerceService
&AWSAccessKeyId=12345&AssociateTag=mytag-20&Operation=ItemSearch
&SearchIndex=VideoGames&Keywords=Mario
&ResponseGroup=Request,ItemAttributes,OfferSummary,Images,Reviews,EditorialReview

The response is big, so I’ll just deal with the relevant parts here. Let’s
suppose we want to get the following information from the first item in the
feed:
-DetailPageURL (The page you direct your users to go to buy the item)
-SmallImage (Graphical representation of the product)
-Title of the game
-LowestNewPrice (lowest price for the item on Amazon)
-Text of a customer review of the item

The simplified feed looks like this:

<ItemSearchResponse>
  <Items>
    <Request>
      <IsValid>
       True
      </IsValid>
    </Request>
    <Item>
      <DetailPageURL>
        http://www.amazon.com/gp.......more stuff
      </DetailPageURL>
      <SmallImage>
       <URL>
         http://ec1.images.... more stuff
       </URL>
      </SmallImage>
      <ItemAttributes>
        <Title>
          Super Mario Bros.
        </Title>
      </ItemAttributes>
      <OfferSummary>
        <LowestNewPrice>
          <FormattedPrice>
            $26.90
          </FormattedPrice>
        </LowestNewPrice>
      </OfferSummary>
      <CustomerReviews>
        <Review>
          <Content>
            Bla Bla Bla. This is the greatest game ever.
          </Content>
        </Review>
      </CustomerReviews>
    </Item>
  </Items>
</ItemSearchResponse>

What to do first? Let’s open the XmlDocument:

String strURL = "http://webservices.amazon.com.....<see above>";
XmlDocument doc = new XmlDocument();
doc.Load(strURL);

//See if the response is valid - Amazon sends this info in a
//node of the XML tree:

XmlNodeList lstIsValid = doc.GetElementsByTagName("IsValid");
//This is nice because .NET automatically drills down a couple
//of levels to find the "IsValid" node tag

if (lstIsValid.Count > 0 && lstIsValid[0].InnerXml == "True")
{
  //InnerXml holds is the actual data from the node
  //Ready to party on the data because the response is valid

  XmlNodeList lstItems = doc.GetElementsByTagName("Item");
  //Also automatically getting info a couple of levels
  //deep - sweet
  //Get a NodeList of the "Item" nodes - they hold our info

  if (lstItems.Count > 0)
  {
    //could use a foreach loop here to get them all
    XmlNode nItem = lstItems[0];
     //all children of the first "item" node

    foreach (XmlNode nChild in nItem.ChildNodes)
    {
      //Clunky way to find a child node.
      //This is the best I could
      //come up with from the MSFT docs.
      //Anybody have a better way?
      if (nChild.Name == "DetailPageURL")  //string compare !
      {
        String strURL = nChild.InnerXml; //our data !
      }
      else if (nChild.Name == "SmallImage")
      {
        //Now we have to look through the children of the
        //SmallImage node:
        foreach (XmlNode nURLImg in nChild.ChildNodes)
        {
          if (nURLImg.Name == "URL")
          {
            String strImage = nChild.InnerXml;  //our data !
          }
        }
      }
      else if (nChild.Name == "ItemAttributes")
      {
        foreach (XmlNode nIA in nChild.ChildNodes)
        {
          //Look through each "ItemAttributes" to find the one
          //we want again
          if (nIA.Name == "Title")
          {
            String strTitle = nIA.InnerXml;  //our data !
          }
        }
      }
      else if (nChild.Name == "OfferSummary")
      {
        foreach (XmlNode nOS in nChild.ChildNodes)
        {
          //looking again
          if (nOS.Name == "LowestNewPrice")
          {
            foreach (XmlNode nLNP in nOS.ChildNodes)
            {
              if (nLNP.Name == "FormattedPrice")
              {
                String strPrice = nLNP.InnerXml;  //our data !
                break; //done looking here.
              }
            }
          }
        }
      }
      else if (nChild.Name == "CustomerReviews")
      {
        foreach (XmlNode nCR in nChild.ChildNodes)
        {
          if (nCR.Name == "Review")
          {
            foreach (XmlNode nRev in nCR.ChildNodes)
            {
              if (nRev.Name == "Content")
              {
                //Our review text!
                String strReview = nRev.InnerXml;
              }
            }
          }
        }
      }
    }
  }
}

You get the idea. Do what you need to do with the data, but this is how to
get it out. I liked the fact that C# would “drill down” a couple of levels to
the relevant child nodes without me precisely specifying like I would have
had to do in XSLT. I did NOT like having to iterate through the nodes and do
string compares to find child nodes. Perhaps there is a better way, but it is
the only one I could find in a lot of searching.

If you want to see the results of parsing the feed in a live site, check out
this games web site that offers game reviews, courtesy of AWS:

midniteblogger