Rev 8027 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
\name{xmlHashTree}\alias{xmlHashTree}\title{Constructors for trees stored as flat list of nodes withinformation about parents and children.}\description{These (and related internal) functions allow us to represent trees asa simple, non-hierarchical collection of nodes along withcorresponding tables that identify the parent and child relationships.This is different from representing a tree as a list of lists of lists... in which each node has a list of its own children. In afunctional language like R, it is not possible then for the childrento be able to identify their parents.We use an environment to represent these flat trees. Since these aremutable without requiring the change to be reassigned, we can modify apart of the tree locally without having to reassign the top-levelobject.We can use either a list (with names) to store the nodes or a hashtable/associative array that uses names. There is a non-trivialperformance difference.}\usage{xmlHashTree(nodes = list(), parents = character(), children = list(),env = new.env(TRUE, parent = emptyenv()))}\arguments{\item{nodes}{ a collection of existing nodes that are to be added tothe tree. These are used to initialize the tree. If this isspecified, you must also specify \code{children} and \code{parents}.}\item{parents}{ the parent relationships for the nodes given by \code{nodes}.}\item{children}{the children relationships for the nodes given by \code{nodes}.}\item{env}{an environment in which the information for the tree willbe stored. This is essentially the tree object as it allows us tomodify parts of the tree without having to reassign the top-levelobject. Unlike most R data types, environments are mutable.}}\value{An \code{xmlHashTree} object has an accessor method via\code{$} for accessing individual nodes within the tree.One can use the node name/identifier in an expression such as\code{tt$myNode} to obtain the element.The name of a node is either its XML node name or if that is alreadypresent in the tree, a machine generated name.One can find the names of all the nodes using the\code{objects} function since these trees are regularenvironments in R.Using the \code{all = TRUE} argument, one can also find the\dQuote{hidden} elements that make define the tree's structure.These are \code{.children} and \code{.parents}.The former is an (hashed) environment. Each element is identified by thenode in the tree by the node's identifier (corresponding to thename of the node in the tree's environment).The value of that element is simply a character vector giving theidentifiers of all of the children of that node.The \code{.parents} element is also an environemnt.Each element in this gives the pair of node and parent identifierswith the parent identifier being the value of the variable in theenvironment. In other words, we look up the parent of a nodenamed 'kid' by retrieving the value of the variable 'kid' in the\code{.parents} environment of this hash tree.The function \code{.addNode} is used to insert a new node into thetree.The structure of this tree allows one to easily travers all nodes,navigate up the tree from a node via its parent. Certain tasks aremore complex as the hierarchy is not implicit within a node.}\references{\url{https://www.w3.org/XML/}}\author{ Duncan Temple Lang }\seealso{\code{\link{xmlTreeParse}}\code{\link{xmlTree}}\code{\link{xmlOutputBuffer}}\code{\link{xmlOutputDOM}}}\examples{f = system.file("exampleData", "dataframe.xml", package = "XML")tr = xmlHashTree()xmlTreeParse(f, handlers = list(.startElement = tr[[".addNode"]]))tr # print the tree on the screen# Get the two child nodes of the dataframe node.xmlChildren(tr$dataframe)# Find the names of all the nodes.objects(tr)# Which nodes have childrenobjects(tr$.children)# Which nodes are leaves, i.e. do not have childrensetdiff(objects(tr), objects(tr$.children))# find the class of each of these leaf nodes.sapply(setdiff(objects(tr), objects(tr$.children)),function(id) class(tr[[id]]))# distribution of number of childrensapply(tr$.children, length)# Get the first A nodetr$A# Get is parent node.xmlParent(tr$A)f = system.file("exampleData", "allNodeTypes.xml", package = "XML")# Convert the documentr = xmlInternalTreeParse(f, xinclude = TRUE)ht = as(r, "XMLHashTree")ht# work on the root node, or any node actuallyas(xmlRoot(r), "XMLHashTree")# Example of making copies of an XMLHashTreeNode object to create a separate tree.f = system.file("exampleData", "simple.xml", package = "XML")tt = as(xmlParse(f), "XMLHashTree")xmlRoot(tt)[[1]]xmlRoot(tt)[[1, copy = TRUE]]table(unlist(eapply(tt, xmlName)))# if any of the nodes had any attributes# table(unlist(eapply(tt, xmlAttrs)))}\keyword{IO}\concept{XML}