title: Isolating data from single XML nodeset in R xml2
body: <p>I am trying to iteratively isolate and manipulate nodesets from an XML document, but I am getting a strange behavior in the xml_find_all() function in the xml2 package in R. Can someone please help me understand the scope of functions applied to a nodeset?</p>
  
  <p>Here is an example:</p>
  
  <pre><code>library( xml2 )
  library( dplyr )
  
  doc &lt;- read_xml( "&lt;MEMBERS&gt;
                       &lt;CUSTOMER&gt;
                          &lt;ID&gt;178&lt;/ID&gt;
                          &lt;FIRST.NAME&gt;Alvaro&lt;/FIRST.NAME&gt;
                          &lt;LAST.NAME&gt;Juarez&lt;/LAST.NAME&gt;
                          &lt;ADDRESS&gt;123 Park Ave&lt;/ADDRESS&gt;
                          &lt;ZIP&gt;57701&lt;/ZIP&gt;
                       &lt;/CUSTOMER&gt;
                       &lt;CUSTOMER&gt;
                          &lt;ID&gt;934&lt;/ID&gt;
                          &lt;FIRST.NAME&gt;Janette&lt;/FIRST.NAME&gt;
                          &lt;LAST.NAME&gt;Johnson&lt;/LAST.NAME&gt;
                          &lt;ADDRESS&gt;456 Candy Ln&lt;/ADDRESS&gt;
                          &lt;ZIP&gt;57701&lt;/ZIP&gt;
                       &lt;/CUSTOMER&gt;  
                    &lt;/MEMBERS&gt;"  )
  
  doc %&gt;% xml_find_all( '//*') %&gt;% xml_path()
  # [1] "/MEMBERS"                        "/MEMBERS/CUSTOMER[1]"           
  # [3] "/MEMBERS/CUSTOMER[1]/ID"         "/MEMBERS/CUSTOMER[1]/FIRST.NAME"
  # [5] "/MEMBERS/CUSTOMER[1]/LAST.NAME"  "/MEMBERS/CUSTOMER[1]/ADDRESS"   
  # [7] "/MEMBERS/CUSTOMER[1]/ZIP"        "/MEMBERS/CUSTOMER[2]"           
  # [9] "/MEMBERS/CUSTOMER[2]/ID"         "/MEMBERS/CUSTOMER[2]/FIRST.NAME"
  #[11] "/MEMBERS/CUSTOMER[2]/LAST.NAME"  "/MEMBERS/CUSTOMER[2]/ADDRESS"   
  #[13] "/MEMBERS/CUSTOMER[2]/ZIP"
  </code></pre>
  
  <p>The object customer.01 is a nodeset that contains data from that customer only.</p>
  
  <pre><code>kids &lt;- xml_children( doc )
  
  customer.01 &lt;- kids[[1]]
  
  customer.01
  # {xml_node}
  # &lt;CUSTOMER&gt;
  # [1] &lt;ID&gt;178&lt;/ID&gt;
  # [2] &lt;FIRST.NAME&gt;Alvaro&lt;/FIRST.NAME&gt;
  # [3] &lt;LAST.NAME&gt;Juarez&lt;/LAST.NAME&gt;
  # [4] &lt;ADDRESS&gt;123 Park Ave&lt;/ADDRESS&gt;
  # [5] &lt;ZIP&gt;57701&lt;/ZIP&gt;
  </code></pre>
  
  <p>Why does the function, applied to the customer.01 nodeset, return the ID for customer.02 as well? </p>
  
  <pre><code>xml_find_all( customer.01, "//MEMBERS/CUSTOMER/ID" )
  # {xml_nodeset (2)}
  # [1] &lt;ID&gt;178&lt;/ID&gt;
  # [2] &lt;ID&gt;934&lt;/ID&gt;
  </code></pre>
  
  <p>How do I return only values from that nodeset?</p>
  
  <p>~~~</p>
  
  <p>Ok, so here's a small wrinkle in the solution below, again related to scope of the xml_find_all() function. It says that it can be applied to a document, node, or nodeset. However...</p>
  
  <p>This case works when applied to a nodeset:</p>
  
  <pre><code>library( xml2 )
  url &lt;- "https://s3.amazonaws.com/irs-form-990/201501279349300635_public.xml"
  doc &lt;- read_xml( url )
  xml_ns_strip( doc )
  nd &lt;- xml_find_all( doc, "//LiquidationOfAssetsDetail|//LiquidationDetail" )
  
  nodei &lt;- nd[[1]]
  nodei
  # {xml_node}
  # &lt;LiquidationOfAssetsDetail&gt;
  # [1] &lt;AssetsDistriOrExpnssPaidDesc&gt;LAND&lt;/AssetsDistriOrExpnssPaidDesc&gt;
  # [2] &lt;DistributionDt&gt;2014-11-04&lt;/DistributionDt&gt;
  # [3] &lt;MethodOfFMVDeterminationTxt&gt;SEE ATTACH&lt;/MethodOfFMVDeterminationTxt&gt;
  # [4] &lt;EIN&gt;abcdefghi&lt;/EIN&gt;
  # [5] &lt;BusinessName&gt;\n  &lt;BusinessNameLine1Txt&gt;GREENSBURG PUBLIC LIBRARY&lt;/BusinessNameLine1Txt&gt;\n&lt;/BusinessName&gt;
  # [6] &lt;USAddress&gt;\n  &lt;AddressLine1Txt&gt;1110 E MAIN ST&lt;/AddressLine1Txt&gt;\n  &lt;CityNm&gt;GREENSBURG&lt;/CityNm&gt;\n  &lt;StateAbbreviationCd&gt;IN&lt;/StateAb ...
  # [7] &lt;IRCSectionTxt&gt;501(C)(3)&lt;/IRCSectionTxt&gt;
  
  xml_text( xml_find_all( nodei, "AssetsDistriOrExpnssPaidDesc" ) )
  # [1] "LAND"
  </code></pre>
  
  <p>But not this one:</p>
  
  <pre><code>nodei &lt;- xml_children( nd[[i]] )
  nodei
  # {xml_nodeset (7)}
  # [1] &lt;AssetsDistriOrExpnssPaidDesc&gt;LAND&lt;/AssetsDistriOrExpnssPaidDesc&gt;
  # [2] &lt;DistributionDt&gt;2014-11-04&lt;/DistributionDt&gt;
  # [3] &lt;MethodOfFMVDeterminationTxt&gt;SEE ATTACH&lt;/MethodOfFMVDeterminationTxt&gt;
  # [4] &lt;EIN&gt;abcdefghi&lt;/EIN&gt;
  # [5] &lt;BusinessName&gt;\n  &lt;BusinessNameLine1Txt&gt;GREENSBURG PUBLIC LIBRARY&lt;/BusinessNameLine1Txt&gt;\n&lt;/BusinessName&gt;
  # [6] &lt;USAddress&gt;\n  &lt;AddressLine1Txt&gt;1110 E MAIN ST&lt;/AddressLine1Txt&gt;\n  &lt;CityNm&gt;GREENSBURG&lt;/CityNm&gt;\n  &lt;StateAbbreviationCd&gt;IN&lt;/StateAb ...
  # [7] &lt;IRCSectionTxt&gt;501(C)(3)&lt;/IRCSectionTxt&gt;
  
  xml_text( xml_find_all( nodei, "AssetsDistriOrExpnssPaidDesc" ) )
  # character(0)
  </code></pre>
  
  <p>I'm guessing this is a problem applying xml_find_all() to all elements of a nodeset rather than a scoping issue? </p>