teaching machines

MeHungry – kruegeba – Homework3

November 6, 2011 by . Filed under cs491 mobile, fall 2011, postmortems.

Imagine you are a poor college student.  You open up your fridge and see you have a very small selection of food.  Now with your trusty MeHungry app, you can type in specific ingredients that you have in your fridge/cabinet and it will return a wide variety of recipes that you can create using those ingredients.

        

The user types into the text box a comma delimited (no spaces) list of ingredients that are available to them.  When they hit the meal time button, the app hits the service at www.recipepuppy.com, where it returns an XML string of recipes containing the recipe title, ingredients, and hyperlink for where the recipe can be found.  One nice feature is that the recipes at the top of the list contain only what the user typed in, and incrementally adds recipes with more and more ingredients.  When you click on an item in the list view, the app takes you to the website via the browser.

The way that recipepuppy.com lets you access there website, is by placing ingredients, a meal, page number, and return data type in the header of the URL.

Design wise I did not do anything to above and beyond besides accessing the internet which is insanely easy to do (through a simple intent call).  But I did decide to process the information from an XML string instead of a JSON string.  I have done a lot with XML through my internship but it was using VB.NET so I decided to explore how Java did it.

XML uses tags very similar to HTML tags, and by layering these tags ones can store information in a unique way.  Here is a small sample of what 1 recipe entry was returned by recipepuppy.com:

<recipe>
<title>Fast Food Tuna Melt</title>
<ingredients>bread,butter,cheese,tuna</ingredients>
<href>http://food.com/tunasandwhich</href>
</recipe>

So after receiving back many entries like this, it is just a matter of parsing through the information.
Java first uses a DocumentBuilderFactory to create a new DocumentBuilder:

DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
DocumentBuilder db = factory.newDocumentBuilder();

You then create an InputSource and pass it a StringReader object that takes in the XML returned by the service and create the main document:

InputSource inStream = new org.xml.sax.InputSource();
inStream.setCharacterStream(new java.io.StringReader(xml));
Document doc = db.parse(inStream);

Finally, its all about starting at the parent nodes (recipe) and then dissect down to the child nodes (title, href, ingredients) and pull the information out of them in as an Element object:

NodeList nodeList = doc.getElementsByTagName(“recipe”);
Recipe[] recipes = new Recipe[nodeList.getLength()];

for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);

Element element = (Element) node;
NodeList titleNode = element.getElementsByTagName(“title”);
NodeList hrefNode = element.getElementsByTagName(“href”);
NodeList ingredNode = element.getElementsByTagName(“ingredients”);

Element titleElement = (Element) titleNode.item(0);
Element hrefElement = (Element) hrefNode.item(0);
Element ingredElement = (Element) ingredNode.item(0);

String title = titleElement.getFirstChild().getNodeValue().trim();
String href = hrefElement.getFirstChild().getNodeValue().trim();
String ingredients = ingredElement.getFirstChild().getNodeValue().trim();

recipes[i] = new Recipe(title, href, ingredients);
}