title: xmlNodeList not limited to selected nodes, and not providing correct parent node
body: <p>I have source XML which has two child nodes of the root node. I pass each of those child nodes to a function as an [xml.xmlNodeList].
  In that function, when I look at the count of the child nodes it is correct, 1 in the first call, passing the initialization node, and 2 in the second call using the processing node. However, if I then try to select the Grandchild nodes of a child nodes, the count goes all wrong. There are only 5 replacement nodes in the windows node under initialization, and 6 under processing, but the results I see are consistently 11 &amp; 22. And yet the actual XML is correct, as shown with the write to console of $nodesToAdd.
  Where am I going so horribly wrong? I don't see anything that could be polluting the pipeline, which is my usual stumbling block.</p>
  
  <pre><code>$sourceXML = [xml] @"
  &lt;tokens&gt;
    &lt;initialization&gt;
      &lt;windows&gt;
        &lt;replacement id="psVersion" type="psVersiontable"&gt;psVersion&lt;/replacement&gt;
        &lt;replacement id="osID" type="regProperty" os="10.0"&gt;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ReleaseId&lt;/replacement&gt;
        &lt;replacement id="osName" type="regProperty"&gt;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductName&lt;/replacement&gt;
        &lt;replacement id="osBuild" type="regProperty"&gt;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentBuildNumber&lt;/replacement&gt;
        &lt;replacement id="osVersion" type="regProperty"&gt;HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\CurrentVersion&lt;/replacement&gt;
      &lt;/windows&gt;
    &lt;/initialization&gt;
    &lt;processing&gt;
      &lt;exitCode&gt;
        &lt;replacement id="successfulExecute" type="string"&gt;0, 3010&lt;/replacement&gt;
        &lt;replacement id="successfulInstall" type="string"&gt;0, 1641, 3010, -2147021886&lt;/replacement&gt;
        &lt;replacement id="successfulUninstall" type="string"&gt;0, 1641, 3010&lt;/replacement&gt;
        &lt;replacement id="wait" type="string"&gt;1618, -2147023278&lt;/replacement&gt;
      &lt;/exitCode&gt;
      &lt;windows&gt;
        &lt;replacement id="commonAppData" type="specialFolder"&gt;CommonApplicationData&lt;/replacement&gt;
        &lt;replacement id="commonDesktop" type="specialFolder"&gt;CommonDesktopDirectory&lt;/replacement&gt;
        &lt;replacement id="commonDocuments" type="specialFolder"&gt;CommonDocuments&lt;/replacement&gt;
        &lt;replacement id="commonProgramFiles" type="specialFolder"&gt;CommonProgramFiles&lt;/replacement&gt;
        &lt;replacement id="commonProgramFilesX86" type="specialFolder"&gt;CommonProgramFilesX86&lt;/replacement&gt;
        &lt;replacement id="commonStartMenu" type="specialFolder"&gt;CommonStartMenu&lt;/replacement&gt;
      &lt;/windows&gt;
    &lt;/processing&gt;
  &lt;/tokens&gt;
  "@
  
  function Set-PxTokenXml {
      param (
          [xml.xmlNodeList]$nodesToAdd
      )
      Write-PxXmlToConsole $nodesToAdd
      Write-Host "$($nodesToAdd.count)"
  
      $testNodes = $nodesToAdd.SelectNodes("//windows/*")
      Write-Host "$($testNodes.count)"
  }
  
  function Write-PxXmlToConsole ($xml) {
      $stringWriter = New-Object System.IO.StringWriter
      $xmlWriter = New-Object System.Xml.XmlTextWriter $stringWriter
      $xmlWriter.Formatting = "indented"
      $xml.WriteTo($xmlWriter)
      $xmlWriter.Flush()
      $stringWriter.Flush()
      Write-Host $stringWriter.ToString()
      Write-Host
      Write-Host
  }
  
  ### MAIN
  Clear-Host
  
  Set-PxTokenXml ($sourceXML.SelectNodes('//initialization/*'))
  Set-PxTokenXml ($sourceXML.SelectNodes('//processing/*'))
  </code></pre>
  
  <p>It seems that while <code>$nodesToAdd</code> is supposed to be a child node, it is actually the entire XML, so "//windows/*" is getting all the replacement nodes that are children of windows, in both initialization and processing. So I tried this, getting the parent node of the passed nodes, and using that to refine the selection.</p>
  
  <pre><code>function Set-PxTokenXml {
      param (
          [xml.xmlNodeList]$nodesToAdd
      )
      #Write-PxXmlToConsole $nodesToAdd
      Write-Host "$($nodesToAdd.count)"
      $parentNode = $nodesToAdd.parentNode.name
      Write-Host "$parentNode"
  
      $testNodes = $nodesToAdd.SelectNodes("//$parentNode/windows/*")
      Write-Host "$($testNodes.count)"
  }
  </code></pre>
  
  <p>But that errors, with the parent node name doubled.</p>
  
  <pre><code>Exception calling "SelectNodes" with "1" argument(s): "'//processing processing/windows/*' has an invalid token."
  </code></pre>
  
  <p>That doubling is related to the number of child nodes. If I add a third child node under processing the I get 'processing processing processing' as the name of the parent node.</p>
  
  <p>The idea was to only pass the nodes I actually want to work with, and keep the number of arguments down. If I pass the entire XML and the name of the node I want to draw from (initialization or processing) I can get it to work. Just curious why xmlNodeList behaves this way, and if there is somehow a way to get a single parent node and make this work with fewer arguments.</p>
  
  <p><strong>EDIT:</strong> Per Ansgar I now have this</p>
  
  <pre><code>function Set-PxTokenXml {
      param (
          [xml.xmlNodeList]$nodesToAdd
      )
      Write-PxXmlToConsole $nodesToAdd
      Write-Host "$($nodesToAdd.count)"
  
      $testNodes = $nodesToAdd.SelectNodes("./windows/*")
      Write-Host "$($testNodes.count)"
  }
  </code></pre>
  
  <p>and now <code>$testNodes.count</code> is coming back 0. For both calls. PS5 if that makes a difference, though I hope not as I need to support PS2, at least in this early part of the code.</p>