title: DomDoc/SimpleXML/XSLT: parsing to add auto-incrementing id attributes to each unique element child of an element
body: <p>I have been troubleshooting this for a while, and I am kind of new to programming.  Even when I find an error, it's very difficult to figure out how to correct it.  Right now, I am trying to figure out how I have used xpath wrong because someone told me that I am using xpath wrong.  I hope someone can give me a jump start by telling me what I am doing wrong, specifically with iterating, if I am doing anything wrong.  This is my last night to work on this project, and I really want to finish it if I can.  So, I could really use help.  Here is the code I am using, with comments:</p>
  
  <pre class="lang-php prettyprint-override"><code>$xml = @simplexml_load_file("original.xml"); //Loading the original file, dubbed original.xml.
  $array_key_target_parent = count($xml-&gt;xpath('/doc/*'); //Puts all of the children of &lt;doc&gt; into an _iterable_ array.
  $key_targets = foreach($array_key_target_parent;){
    foreach($array_key_target_parent as $single_target){ // I tried foreach($array_key_target_parent[$i]).  It doesn't work, so don't even go there.
      $current_target = current($single_target);
      count($xml-&gt;xpath('/doc/$current_target/*');
    }
  } */ ////Puts the targets for keying into iterable arrays.  =&gt;1 makes the array start from 1, so the id's will be right.
  
  
  /* At this point, we have multiple elements that we want to key, each having a unique name.  There's &lt;element_type1a&gt; and &lt;element_type1b&gt;, etc.  We want each one to have its own id set.  So, we have to embed iteration within iteration. */
  foreach($key_target){ //This will ensure that every unique element that we want to key gets its key set.
    {
    $id = current($key_target=&gt;1); //This allows us to reset the id to 1 (=&gt;1), each time the key algorithm starts for a new element.
    foreach($key_target as $id){ //I tried for($i=0, $key_target[$i]; $i&gt;$key_target; $i++), and it didn't work, so don't even go there.
      addAttribute('id', '$id');
    }
  }  //Adds an 'id' attribute and a unique number to each target.
  
  $xml-&gt;asXML("new.xml"); //saves the output as a new xml document, new.xml
  </code></pre>
  
  <p>I also have a generic XML file:</p>
  
  <pre><code>&lt;doc&gt;
      &lt;info_type1&gt;
          &lt;element_type1a&gt;not_unique_data&lt;/element_type1a&gt;
          &lt;element_type1b&gt;unique_data&lt;/element_type1b&gt;
          &lt;element_type2a&gt;not_unique_data&lt;/element_type2a&gt;
          &lt;element_type2b&gt;not_unique_data&lt;/element_type2b&gt;
          &lt;element_type2c lang="fr"&gt;not_unique_data&lt;/element_type2c&gt;
          &lt;!-- ... ---&gt;
          &lt;element_typeNxM&gt;unique_data&lt;/element_typeNxM&gt;
      &lt;/info_type1&gt;
      &lt;info_type2&gt;
          &lt;element_type1a&gt;repeat_data(info_type1_element1a)&lt;/element_type1a&gt;
          &lt;element_type2a&gt;not_unique_data&lt;/element_type2a&gt;
      &lt;/info_type2&gt;
      &lt;!-- ... ---&gt;
      &lt;info_typeN&gt;
          &lt;descendants&gt;&lt;/descendants&gt;
      &lt;/info_typeN&gt;
  &lt;/doc&gt;
  </code></pre>
  
  <p>Desired output:</p>
  
  <pre><code>&lt;datatables&gt;
      &lt;table id="element_type1"&gt;
          &lt;element_type1a id="1"&gt;unique_data&lt;/element_type1a&gt;
          &lt;element_type1b id="2"&gt;unique_data&lt;/element_type1b&gt;
          &lt;!-- ... ---&gt;
          &lt;element_type1N id="M"&gt;unique_data&lt;/element_type1N&gt;
      &lt;/table&gt;
      &lt;table id="element_type2"&gt;
          &lt;element_type2a id="1"&gt;unique_data&lt;/element_type2a&gt;
          &lt;element_type2b id="2"&gt;unique_data&lt;/element_type2b&gt;
          &lt;!-- ... ---&gt;
          &lt;element_type2N id="M"&gt;unique_data&lt;/element_type2N&gt;
      &lt;/table&gt;
      &lt;table id="element_type2_fr"&gt;
          &lt;element_type2a lang="fr" id="1"&gt;unique_data&lt;/element_type2a&gt;
          &lt;element_type2b lang="fr" id="2"&gt;unique_data&lt;/element_type2&gt;
          &lt;!-- ... (there are five languages) ---&gt;
          &lt;element_type2N lang="fr" id="M"&gt;unique_data&lt;/element_type2N&gt;
      &lt;/table&gt;
      &lt;!-- ... ---&gt;
      &lt;table id="element_typeN"&gt;
          &lt;descendants&gt;&lt;/descendants&gt;
      &lt;/table&gt;
  &lt;/datatables&gt;
  </code></pre>
  
  <p>and </p>
  
  <pre><code>&lt;intermediary_tables&gt;
      &lt;table id="intermediary_table_type1xtype2"&gt;
          &lt;element id="1"&gt;
              &lt;type1ID&gt;1&lt;/type1ID&gt;
              &lt;type2ID&gt;1&lt;/type2ID&gt;
          &lt;/element&gt;
          &lt;element id="2"&gt;
              &lt;type1ID&gt;1&lt;/type1ID&gt;
              &lt;type2ID&gt;2&lt;/type2ID&gt;
          &lt;/element&gt;
          &lt;element id="3"&gt;
              &lt;type1ID&gt;2&lt;/type1ID&gt;
              &lt;type2ID&gt;1&lt;/type2ID&gt;
          &lt;/element&gt;
          &lt;element id="4"&gt;
              &lt;type1ID&gt;2&lt;/type1ID&gt;
              &lt;type2ID&gt;2&lt;/type2ID&gt;
          &lt;/element&gt;
          &lt;!-- ... ---&gt;
          &lt;element id="N"&gt;
              &lt;type1ID&gt;M&lt;/type1ID&gt;
              &lt;type2ID&gt;Z&lt;/type2ID&gt;
          &lt;/element_type2N&gt;
      &lt;/table&gt;
  
      &lt;table id="intermediary_table_typeMxtypeN"&gt;
          &lt;descendants&gt;&lt;/descendants&gt;
      &lt;/table&gt;
  &lt;/intermediary_tables&gt;
  </code></pre>
  
  <p>I have also seen many very similar questions asked, and I have some resources that I gathered from them and read: </p>
  
  <ul>
  <li><a href="http://www.ibm.com/developerworks/xml/library/x-xmlphp1/index.html" rel="nofollow">http://www.ibm.com/developerworks/xml/library/x-xmlphp1/index.html</a></li>
  <li><a href="http://www.php.net/manual/en/simplexmlelement.addattribute.php" rel="nofollow">http://www.php.net/manual/en/simplexmlelement.addattribute.php</a></li>
  <li><a href="http://www.learn-xslt-tutorial.com/" rel="nofollow">http://www.learn-xslt-tutorial.com/</a></li>
  <li><a href="http://msdn.microsoft.com/en-us/library/ms256103.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/ms256103.aspx</a></li>
  <li><a href="http://php.net/manual/en/class.domdocument.php" rel="nofollow">http://php.net/manual/en/class.domdocument.php</a></li>
  </ul>
  
  <p>These are the most useful links:</p>
  
  <ul>
  <li><a href="http://www.capcourse.com/Library/NormalizingXML/Part1.html" rel="nofollow">http://www.capcourse.com/Library/NormalizingXML/Part1.html</a></li>
  <li><a href="http://forums.tizag.com/showthread.php?t=17821" rel="nofollow">http://forums.tizag.com/showthread.php?t=17821</a></li>
  </ul>
  
  <p>And I found that none of the applications of the questions were able to produce the result I am trying to achieve.  The exception, though, is the capcourse.com link.  It's geared towards a graduated CS audience, and it seems like they're doing the same thing, except the ID's they are using aren't autoincrementing.  The algorithm they use is extremely complex, and they haven't commented their code at all.  They're using a namespace within their namespace for some reason, and even though it's the closest I can find, I can't reproduce it in the slightest.</p>
  
  <hr>
  
  <p><strong>Update</strong></p>
  
  <p>Real-world extract from an XML document that I would like to parse to change the data structure:</p>
  
  <pre><code>&lt;?xml version="1.0"?&gt;
  &lt;!DOCTYPE catalog [
  &lt;!ELEMENT catalog (entry*)&gt;
  &lt;!ELEMENT entry (ent_seq, country*, arist+, info?, title+)&gt;&lt;!-- Entries consist of the name of the album, artist, and more information about the CD.  Each entry must contain an artist and an album title. --&gt;
  &lt;!ELEMENT ent_seq (#PCDATA)&gt;&lt;!-- A unique numeric sequence, showing the entry number --&gt;
  &lt;!ELEMENT title (#PCDATA)&gt;&lt;!-- The title of the album/the album name. --&gt;
  &lt;!ELEMENT artist (band+, name, nickname*)&gt;&lt;!-- The name of the band, and if there was a famous artist, his name and nickname.  Must contain a band element. --&gt;
  &lt;!ELEMENT band (#PCDATA)&gt;&lt;!-- The name of the band. --&gt;
  &lt;!ELEMENT name (#PCDATA)&gt;&lt;!-- The name of any famous artist in the band. --&gt;
  &lt;!ELEMENT nickname (#PCDATA)&gt;&lt;!-- The nickname of the popular artist that precedes the nickname element, from the band. --&gt;
  &lt;!ELEMENT country (#PCDATA)&gt;&lt;!-- Specifies countries where the album was released --&gt;
  &lt;!ELEMENT company (name, country)&gt;&lt;!-- Company/producer info.  The company's name is in the name element, and the country where the company originated is in the country element. --&gt;
  &lt;!ELEMENT name (#PCDATA)&gt;&lt;!-- The name of the producer --&gt;
  &lt;!ELEMENT country (#PCDATA)&gt;&lt;!-- The country where the company does its primary business --&gt;
  &lt;!ELEMENT year (#PCDATA)&gt;&lt;!-- The year of the album's release --&gt;
  &lt;!ELEMENT info (link*, bibl*)&gt;&lt;!-- Additional info, including links and bibliography information --&gt;
  &lt;!ELEMENT link (#PCDATA)&gt;&lt;!-- Links where people can read more about the album --&gt;
  &lt;!ELEMENT bibl (#PCDATA)&gt;&lt;!-- Bibliography text about the artist --&gt;
  ]&gt;
  &lt;catalog&gt;
    &lt;cd&gt;
      &lt;ent_seq&gt;1&lt;/ent_seq&gt;
      &lt;title&gt;For Your Love&lt;/title&gt;
      &lt;artist&gt;
        &lt;name&gt;The Yardbirds&lt;/name&gt;
        &lt;name&gt;Eric Clapton&lt;/name&gt;
        &lt;nickname&gt;Slowhand&lt;/nickname&gt;
      &lt;/artist&gt;
      &lt;country&gt;USA&lt;/country&gt;
      &lt;country&gt;UK&lt;/country&gt;
      &lt;company&gt;
        &lt;name&gt;Sweet Music&lt;/name&gt;
        &lt;country&gt;USA&lt;/country&gt;
      &lt;/company&gt;
      &lt;year&gt;1965&lt;/year&gt;
      &lt;info&gt;
        &lt;link&gt;http://en.wikipedia.org/wiki/For_Your_Love&lt;/link&gt;
      &lt;/info&gt;
    &lt;/cd&gt;
    &lt;cd&gt;
      &lt;ent_seq&gt;2&lt;/ent_seq&gt;
      &lt;title&gt;Splish Splash&lt;/title&gt;
      &lt;artist&gt;
        &lt;name&gt;Roberto Carlos&lt;/name&gt;
        &lt;nickname&gt;The King&lt;/nickname&gt;
      &lt;/artist&gt;
      &lt;country&gt;USA&lt;/country&gt;
      &lt;country&gt;Brazil&lt;/country&gt;
      &lt;country&gt;Italy&lt;/country&gt;
      &lt;company&gt;
        &lt;name&gt;Sweet Music&lt;/name&gt;
      &lt;country&gt;Brazil&lt;/country&gt;
      &lt;/company&gt;
      &lt;year&gt;1965&lt;/year&gt;
    &lt;/cd&gt;
    &lt;cd&gt;
      &lt;ent_seq&gt;3&lt;/ent_seq&gt;
      &lt;title&gt;How Great Thuo Art&lt;/title&gt;
      &lt;artist&gt;
        &lt;name&gt;Elvis Presley&lt;/name&gt;
        &lt;nickname&gt;The King&lt;/nickname&gt;
        &lt;nickname&gt;The King of Rock 'n Roll&lt;/nickname&gt;
      &lt;/artist&gt;
      &lt;country&gt;USA&lt;/country&gt;
      &lt;country&gt;Canada&lt;/country&gt;
      &lt;country&gt;UK&lt;/country&gt;
      &lt;company&gt;
        &lt;name&gt;Felton Jarvis&lt;/name&gt;
        &lt;country&gt;USA&lt;/country&gt;
      &lt;/company&gt;
      &lt;year&gt;1965&lt;/year&gt;
    &lt;/cd&gt;
    &lt;cd&gt;
      &lt;ent_seq&gt;4&lt;/ent_seq&gt;
      &lt;title&gt;Big Willie style&lt;/title&gt;
      &lt;artist&gt;
        &lt;band&gt;Will Smith&lt;/band&gt;
        &lt;name&gt;Will Smith&lt;/name&gt;
      &lt;/artist&gt;
      &lt;country&gt;USA&lt;/country&gt;
      &lt;company&gt;Columbia&lt;/company&gt;
      &lt;year&gt;1997&lt;/year&gt;
    &lt;/cd&gt;
    &lt;cd&gt;
      &lt;ent_seq&gt;5&lt;/ent_seq&gt;
      &lt;title&gt;Empire Burlesque&lt;/title&gt;
      &lt;artist&gt;
        &lt;band&gt;Bob Dylan and Boby Rockhammer&lt;/band&gt;
        &lt;name&gt;Bob Dylan&lt;/name&gt;
        &lt;name&gt;Boby Rockhammer&lt;/name&gt;
      &lt;/artist&gt;
      &lt;country&gt;USA&lt;/country&gt;
      &lt;country&gt;India&lt;/country&gt;
      &lt;company&gt;Columbia&lt;/company&gt;
      &lt;year&gt;1985&lt;/year&gt;
    &lt;/cd&gt;
    &lt;cd&gt;  &lt;!-- Update part 1: New Entry --&gt;
      &lt;ent_seq&gt;6&lt;/ent_seq&gt;
      &lt;title&gt;Merry Christmas&lt;/title&gt;
      &lt;title&gt;White Christmas&lt;/title&gt;
      &lt;artist&gt;
        &lt;name&gt;Bing Crosby&lt;/name&gt;
      &lt;artist&gt;
      &lt;country&gt;USA&lt;/country&gt;
      &lt;company&gt;MCA Records&lt;/company&gt;
      &lt;year&gt;1995&lt;/year&gt;
    &lt;/cd&gt; &lt;!-- End update part 1--&gt;
  &lt;/catalog&gt;
  </code></pre>
  
  <p>Real-world example of desired output sample:</p>
  
  <pre><code>&lt;datatable&gt;
    &lt;table id="album title"&gt;
      &lt;title id="1"&gt;For your Love&lt;/title&gt;
      &lt;title id="2"&gt;Splish Splash&lt;/title&gt;
      &lt;title id="3"&gt;How Great Thuo Art&lt;/title&gt;
      &lt;title id="4"&gt;Big Willie style&lt;/title&gt;
      &lt;title id="5"&gt;Empire Burlesque&lt;/title&gt;
      &lt;title id="6"&gt;Merry Christmas&lt;/title&gt; &lt;!-- Update part 2: New output --&gt;
      &lt;title id="7"&gt;White Christmas&lt;/title&gt; &lt;!-- Update part 2: New output --&gt;
    &lt;/table&gt;
    &lt;table id="Band Name"&gt;
      &lt;artist id="1"&gt;The Yardbirds&lt;/artist&gt;
      &lt;artist id="2"&gt;Roberto Carlos&lt;/artist&gt;
      &lt;artist id="3"&gt;Elvis Presley&lt;/artist&gt;
      &lt;artist id="4"&gt;Will Smith&lt;/artist&gt;
      &lt;artist id="5"&gt;Bob Dylan and Boby Rockhammer&lt;/artist&gt;
      &lt;artist id="6"&gt; &lt;!-- Update part 2: New output --&gt;
    &lt;/table&gt;
    &lt;table id="artist name"&gt;
      &lt;artist id="1"&gt;Eric Clapton&lt;/artist&gt;
      &lt;artist id="2"&gt;Roberto Carlos&lt;/artist&gt;
      &lt;artist id="3"&gt;Elvis Presley&lt;/artist&gt;
      &lt;artist id="4"&gt;Will Smith&lt;/artist&gt;
      &lt;artist id="5"&gt;Bob Dylan&lt;/artist&gt;
      &lt;artist id="6"&gt;Boby Rockhammer&lt;/artist&gt;
      &lt;artist id="7"&gt;Bing Crosby&lt;/artist&gt; &lt;!-- Update part 2: New output --&gt;
    &lt;/table&gt;
    &lt;table id="nickname"&gt;
      &lt;nickname id="1"&gt;Slowhand&lt;/nickname&gt;
      &lt;nickname id="2"&gt;The King&lt;/nickname&gt;
      &lt;nickname id="3"&gt;The King of Rock 'n Roll&lt;/nickname&gt;
    &lt;/table&gt;
  &lt;/datatable&gt;
  </code></pre>
  
  <p>and </p>
  
  <pre><code>&lt;intermediarytable&gt;
    &lt;table id="artist by band name"&gt;
      &lt;entry id="1"&gt;
        &lt;band_id&gt;1&lt;/band_id&gt;
        &lt;artist_id&gt;1&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="2"&gt;
        &lt;band_id&gt;2&lt;/band_id&gt;
        &lt;artist_id&gt;2&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="3"&gt;
        &lt;band_id&gt;3&lt;/band_id&gt;
        &lt;artist_id&gt;3&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="4"&gt;
        &lt;band_id&gt;4&lt;/band_id&gt;
        &lt;artist_id&gt;4&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="5"&gt;
        &lt;band_id&gt;5&lt;/band_id&gt;
        &lt;artist_id&gt;5&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="6"&gt;
        &lt;band_id&gt;5&lt;/band_id&gt;
        &lt;artist_id&gt;6&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="7"&gt;
        &lt;band_id&gt;6&lt;/band_id&gt;
        &lt;artist_id&gt;7&lt;/artist_id&gt;
      &lt;/entry&gt;
    &lt;/table&gt;
    &lt;table id="artist by nickname"&gt;
      &lt;entry id="1"&gt;
        &lt;artist_id&gt;1&lt;/artist_id&gt;
        &lt;nickname_id&gt;1&lt;/artist_id&gt;
      &lt;/entry&gt;
      &lt;entry id="2"&gt;
        &lt;artist_id&gt;2&lt;/artist_id&gt;
        &lt;nickname_id&gt;2&lt;/nickname_id&gt;
      &lt;/entry&gt;
      &lt;entry id="3"&gt;
        &lt;artist_id&gt;2&lt;/artist_id&gt;
        &lt;nickname_id&gt;3&lt;/nickname_id&gt;
      &lt;/entry&gt;
      &lt;entry id="4"&gt;
        &lt;artist_id&gt;3&lt;/artist_id&gt;
        &lt;nickname_id&gt;3&lt;/nickname_id&gt;
      &lt;/entry&gt;
    &lt;/table&gt;
  &lt;/intermediarytable&gt;
  </code></pre>
  
  <p><strong>--UPDATE-- There's an issue in which two elements share the same entry ID</strong></p>
  
  <p>In another XML doc I have,</p>
  
  <pre><code>&lt;entry id="1"&gt;
    &lt;word&gt;blue&lt;/word&gt;
    &lt;word&gt;beryl&lt;/word&gt;
    &lt;word lang="SP"&gt;azul&lt;/word&gt;
  &lt;/entry&gt;
  </code></pre>
  
  <p>and I want the output to be </p>
  
  <p>Data Tables:</p>
  
  <pre><code>&lt;table id="en"&gt;
    &lt;word lang="en" id="0"&gt;blue&lt;/word&gt;
    &lt;word lang="en" id="1"&gt;beryl&lt;/word&gt;
  &lt;/table&gt;
  &lt;table id="sp"&gt;
    &lt;word lang="sp" id="0"&gt;azul&lt;/word&gt;
  &lt;/table&gt;
  </code></pre>
  
  <p>Intermediary Table:</p>
  
  <pre><code>&lt;table id="translation id"&gt;
    &lt;en_sp id="0"&gt; &lt;!-- en_sp means English-to-Spanish --&gt;
      &lt;en&gt;0&lt;/en&gt;
      &lt;sp&gt;0&lt;/sp&gt;
    &lt;/en_sp&gt;
    &lt;en_sp&gt;
      &lt;en&gt;1&lt;/en&gt;
      &lt;sp&gt;0&lt;/sp&gt;
    &lt;/en_sp&gt;
  &lt;/table&gt;
  </code></pre>