title: xpath and r - create a key table
body: <p>I'm new to the xml package for r and new to xpath.  I have a very large xml file that I am parsing.  I wrote some code using loops that works but takes too long, so I am writing more efficient code using xpath. 
  The xml looks something like this:</p>
  
  <pre><code>...
  &lt;person personId="1"&gt;
  &lt;personNames&gt;
  &lt;personName nameId="1000"&gt;
  &lt;first&gt;Joe&lt;last&gt;
  &lt;last&gt;Jones&lt;last&gt;
  &lt;/personName&gt;
  &lt;personName nameId="1001"&gt;
  &lt;first&gt;Joseph&gt;&lt;first&gt;
  &lt;last&gt;Jones&lt;last&gt;
  &lt;/personName&gt;
  &lt;personName nameId="1002"
  &lt;first&gt;The One and only Joe&lt;first&gt;
  &lt;/personName&gt;
  &lt;/personNames&gt;
  &lt;/person&gt;
  ...
  </code></pre>
  
  <p>Some people have one name, some have more.  Some people have first and last names, some of just a first name or just a last name.  So, I need to be careful.  </p>
  
  <p>I was able to efficiently create a data frame of first and last names using xpath:</p>
  
  <pre><code>library(XML)
  doc&lt;-xmlTreeParse("People.xml",useInternalNodes = TRUE)
  top&lt;-xmlRoot(doc)
  First&lt;-as.character(xpathApply(top,"//person/personNames/personName/first", xmlValue))
  name_id&lt;-as.integer(xpathApply(top,"//person/personNames/personName[first]/@nameId"))
  FirstNames&lt;-data.frame(TMS_name_id=name_id,first=First)
  Last&lt;-as.character(xpathApply(top,"//person/personNames/personName/last", xmlValue))
  name_id&lt;-as.integer(xpathApply(top,"//person/personNames/personName[last]/@nameId"))
  LastNames&lt;-data.frame(name_id=name_id,last=Last)
  Names&lt;-merge(x=FirstNames,y=LastNames,by="name_id",all=TRUE)
  </code></pre>
  
  <p>My Names data frame looks good.  It has the nameId, first name, and last name of every person.  If a first or last name is missing, it is a null.  It generated in a few minutes (610K rows!).  Awesome.</p>
  
  <p>The problem is associating these names with the parent personId.  I assume I need to loop through the names in my data frame, and grab the personId that has the correct nameId attribute, but I am unable to do this.  For example, the following code gives me a null result:</p>
  
  <pre><code>xpathSApply(top,"//person/personNames/personName[@nameId="1000"]/@personId")
  </code></pre>
  
  <p>I am expecting a result of 1.  What is the most efficient way to add a column in my data frame for personId?</p>
  
  <p>Given the sample above, I want a data frame that looks like this:</p>
  
  <pre><code>nameId  first                  last                  personId
  1000    Joe                    Jones                 1
  1001    Joseph                 Jones                 1
  1002    The one and only Joe   &lt;NA&gt;                  1
  </code></pre>