Below is a snippet of GML taken from the website for this assignment. Notice that it contains the xml tag and the doc (root) tag so that we have well-formed XML that we can process. You may want to create a similar snippet for testing your code. ALABAMA Autauga County -86641472 32542207 Baldwin County -87754736 30654881 CONNECTICUT Fairfield County -73371027 41225499 Hartford County -72734983 41807100 1. Draw a tree corresponding to the DOM model for the above XML. 2. Before we figure out how to use handlers, let's explore the tree that we get when we read the xml into R. > gtree = xmlRoot(xmlTreeParse("countiesEx.xml") > xmlSApply(gtree, xmlName) state state "state" "state" > xmlSApply(gtree, function(node) xmlSApply(node, xmlName)) state state name "name" "name" county "county" "county" county "county" "county" # Let's look at the name node in the first state > gtree[["state"]][["name"]] ALABAMA # To pick out the attribute from the name node we use xmlAttrs > xmlAttrs(gtree[[1]][["name"]]) abbreviation "AL" 3. How would you find the value of the X tag in the Autauga County node? How do you find all of the X tags in a state node? > gtree[[1]][["county"]] Autauga County -86641472 32542207 4. Now consider the following simple handler function that will be called every time that xmlTreeParse encounters a state node StateHandler = function() { counties = list() state1 = function(x) { stateAbb <- xmlAttrs(x[["name"]]) counties[[ stateAbb ]] <<- paste("this is a test", stateAbb) # Notice the assignment to the counties object in the parent space } list(state = state1, .value = function() counties) # The function called .value simply returns the value of counties # The function StatHandler returns a list of two functions } # Notice that the argument asTree says that we do not want to # create an XMLDocument tree from the call. # What is returned is the handlers object. > cL = xmlTreeParse(file = "countiesEx.xml", handlers = StateHandler(), asTree = FALSE) > cL > cL$.value() 5. Here's a more complex set of handler functions, one for the state node and one for the county node. It's just a shell for you to add to ShellHandlers = function() { counties = list() countyLocs = data.frame(X = NA, Y = NA) countyLocs = countyLocs[FALSE, ] county1 = function(x) { ctyname <- xmlValue(x[["name"]]) print(ctyname) # What you really want here is to build the countyLocs data frame # You need to use global assignment so that the counties are kept # from one call to the next } state1 = function(x) { stateAbb <- xmlAttrs(x[["name"]]) counties[[ stateAbb ]] <<- paste("this is a test", stateAbb) # What you really want to put into the counties list is the # data frame that you built in the county handler } list(state = state1, county = county1, .value = function() counties) } > countyLocs = xmlTreeParse(file = "countiesEx.xml", handlers = ShellHandlers(), asTree = FALSE)$.value()