library(XML)
genDoc <- function(i, j)
  paste(c("<h>",
          "  <i>", rep("    <s>1</s>", i), "  </i>",
          "  <j>", rep("    <s>2</s>", j), "  </j>",
          "</h>"), collapse="\n")
cat(genDoc(3, 2))
## <h>
##   <i>
##     <s>1</s>
##     <s>1</s>
##     <s>1</s>
##   </i>
##   <j>
##     <s>2</s>
##     <s>2</s>
##   </j>
## </h>

XML::xmlToList(xmlTreeParse(genDoc(1, 1), asText=T))
## $i.s
## [1] "1"
## 
## $j.s
## [1] "2"
XML::xmlToList(xmlTreeParse(genDoc(2, 2), asText=T))
##   i   j  
## s "1" "2"
## s "1" "2"
XML::xmlToList(xmlTreeParse(genDoc(1, 3), asText=T))
## $i
## $i$s
## [1] "1"
## 
## 
## $j
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
XML::xmlToList(xmlTreeParse(genDoc(2, 3), asText=T))
## $i
## $i$s
## [1] "1"
## 
## $i$s
## [1] "1"
## 
## 
## $j
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"

xmlToList <- function (node, addAttributes = TRUE, simplify = FALSE) 
{
  if (is.character(node)) 
    node = xmlParse(node)
  if (inherits(node, "XMLAbstractDocument")) 
    node = xmlRoot(node)
  if (any(inherits(node, c("XMLTextNode", "XMLInternalTextNode")))) 
    xmlValue(node)
  else if (xmlSize(node) == 0) 
    xmlAttrs(node)
  else {
    if (is.list(node)) {
      tmp = vals = (if (simplify) 
        xmlSApply
                    else xmlApply)(node, xmlToList, addAttributes)
      tt = xmlSApply(node, inherits, c("XMLTextNode", "XMLInternalTextNode"))
    }
    else {
      tmp = vals = (if (simplify) 
        xmlSApply
                    else xmlApply)(node, xmlToList, addAttributes)
      tt = xmlSApply(node, inherits, c("XMLTextNode", "XMLInternalTextNode"))
    }
    vals[tt] = (if (simplify) 
      sapply
                else lapply)(vals[tt], function(x) x[[1]])
    if (length(attrs <- xmlAttrs(node)) > 0) {
      if (addAttributes) 
        vals[[".attrs"]] = attrs
      else attributes(vals) = as.list(attrs)
    }
    if (any(tt) && length(vals) == 1 && names(vals) == "text")
      vals[[1]]
    else vals
  }
}
xmlToList(xmlTreeParse(genDoc(1, 1), asText=T))
## $i
## $i$s
## [1] "1"
## 
## 
## $j
## $j$s
## [1] "2"
xmlToList(xmlTreeParse(genDoc(2, 2), asText=T))
## $i
## $i$s
## [1] "1"
## 
## $i$s
## [1] "1"
## 
## 
## $j
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
xmlToList(xmlTreeParse(genDoc(1, 3), asText=T))
## $i
## $i$s
## [1] "1"
## 
## 
## $j
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
xmlToList(xmlTreeParse(genDoc(2, 3), asText=T))
## $i
## $i$s
## [1] "1"
## 
## $i$s
## [1] "1"
## 
## 
## $j
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
## 
## $j$s
## [1] "2"
sessionInfo()
## R version 3.0.2 (2013-09-25)
## Platform: x86_64-pc-linux-gnu (64-bit)
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] XML_3.98-1.1 knitr_1.5.21
## 
## loaded via a namespace (and not attached):
## [1] evaluate_0.5.2 formatR_0.10.4 stringr_0.6.2  tools_3.0.2