//category[ not (text()=following::category/text())]Discussion: The solution above appears to have two problems:
/items/item[not(category=preceding-sibling::item/category)]/categoryThis query is safer and faster.
The first thing to do is to get yourself registered as a developer. Do this now. It may take some time, and it will prevent you from doing anything else.
Where you might expect an object oriented architecture to define a base class, containing common attributes, and subclasses that specialized the base class with appropriate additional attributes, ECS appears to define a single class with all of the attributes that any object might have. It then populates only the relevant attributes, leaving the rest null.
Response groups seem to give some control over what gets populated, and what doesn't. They are represented as case-sensitive strings. The response groups "Large" and "ItemAttributes" seem to work pretty well. You will have to experiment to find out what others do. You can find the list of ResponseGroups by starting at the documentation page and navigating to API Reference -> ResponseGroups.
Search Index values seem to be, sort of, the "floor" of the department store on which you are searching. Third floor: power tools and kitchen items. A list of Search Indices can be found, starting on the documentation page above, by navigating to API Reference -> Search Index Values. Again, these are case-sensitive strings: be sure you spell them correctly.
First create the connection:
new AWSECommerceServiceLocator() .getAWSECommerceServicePort()Next create the query:
ItemSearchRequest req = new ItemSearchRequest();
req.setResponseGroup(RESPONSE_GROUPS);
req.setSearchIndex(SEARCH_INDEX);
req.setKeywords(item);
_ItemSearch search = new _ItemSearch();
search.setSubscriptionId(SUBSCRIPTION_ID);
search.setRequest(new ItemSearchRequest[]{req});
This query will search for keywords matching the value of the variable "item".
Next run the query:
for (int i = 0; i < RETRIES; i++) {
try { return connection.itemSearch(search); }
catch (Exception e) {
if (err == null) { err = e; }
sLogger.warn("Failed connecting to Amazon", e);
}
}
It seems to be a good idea to retry once or twice: connections do seem to
fail every now and then.
Finally check for errors and format results:
_Items[] items = resp.getItems();
_Errors errors = items[0].getRequest().getErrors();
if (errors == null) {
formatResponse(items);
return;
}
_Errors_Error[] e = errors.getError();
System.out.println("Error:");
for (int i = 0; i < e.length; i++) {
System.err.println(" " + e[i].getMessage());
}
While I can't guarantee it, it appears that all items contain references
to the same error, thus items[0].getRequest().getErrors() will get
whatever error there is.
public static final String SUBSCRIPTION_ID = System.getProperty("amazon.ecs.id");
If, when you start tomcat, then, you simply add:
-Damazon.ecs.id=098109987233408977414234to the startup command, you never need to include the id in your code.
ItemSearchRequest req = new ItemSearchRequest(); req.setResponseGroup(RESPONSE_GROUPS); req.setSearchIndex(SEARCH_INDEX); req.setAuthor(item); ...
item[j].getItemAttributes().getListPrice().getFormattedPrice()is sure to generate NullPointerExceptions.
ItemSearchRequest req = new ItemSearchRequest();
req.setResponseGroup(RESPONSE_GROUPS);
req.setSearchIndex(SEARCH_INDEX);
req.setAuthor(item);
req.setSort("pricerank");
...
again, the sort specifier is a case-sensitive string. The various
legal values can be found from the documentation page above, at
API Reference -> Sort Values
Go wild