title: Insert a new XML node after another node
body: <p>I'm really struggling to manipulate some XML in PowerShell that I need to send back to a web service as a body. Could anyone help me get the XML laid out the way it needs to be please?</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;EdgeGateway&gt;
  &lt;Configuration&gt;
      &lt;GatewayInterfaces&gt;
          &lt;GatewayInterface&gt;
              &lt;InterfaceType&gt;uplink&lt;/InterfaceType&gt;
              &lt;SubnetParticipation&gt;
                  &lt;Gateway&gt;1.2.3.4&lt;/Gateway&gt;
                  &lt;Netmask&gt;255.255.255.240&lt;/Netmask&gt;
                  &lt;IpAddress&gt;1.2.3.5&lt;/IpAddress&gt;
  # Missing the IpRange XML section - defined below
                  &lt;UseForDefaultRoute&gt;true&lt;/UseForDefaultRoute&gt;
              &lt;/SubnetParticipation&gt;
              &lt;UseForDefaultRoute&gt;true&lt;/UseForDefaultRoute&gt;
          &lt;/GatewayInterface&gt;
      &lt;/GatewayInterfaces&gt;
  &lt;/Configuration&gt;
  &lt;/EdgeGateway&gt;
  </code></pre>
  
  <p>needs to become:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;EdgeGateway&gt;
  &lt;Configuration&gt;
      &lt;GatewayInterfaces&gt;
          &lt;GatewayInterface&gt;
              &lt;InterfaceType&gt;uplink&lt;/InterfaceType&gt;
              &lt;SubnetParticipation&gt;
                  &lt;Gateway&gt;1.2.3.4&lt;/Gateway&gt;
                  &lt;Netmask&gt;255.255.255.240&lt;/Netmask&gt;
                  &lt;IpAddress&gt;1.2.3.5&lt;/IpAddress&gt;
  # New Content added here
                  &lt;IpRanges&gt;
                      &lt;IpRange&gt;
                          &lt;StartAddress&gt;1.2.3.5&lt;/StartAddress&gt;
                          &lt;EndAddress&gt;1.2.3.5&lt;/EndAddress&gt;
                      &lt;IpRange&gt;
                  &lt;/IpRanges&gt;
   # End of new content
                  &lt;UseForDefaultRoute&gt;true&lt;/UseForDefaultRoute&gt;
              &lt;/SubnetParticipation&gt;
              &lt;UseForDefaultRoute&gt;true&lt;/UseForDefaultRoute&gt;
          &lt;/GatewayInterface&gt;
      &lt;/GatewayInterfaces&gt;
  &lt;/Configuration&gt;
  &lt;/EdgeGateway&gt;
  </code></pre>
  
  <p>So far I've been able to create new XML Nodes/Elements for the new content, but I cannot get it to be inserted at the correct place. I can get the <code>AppendChild()</code> method to work, but it puts the content after the <code>&lt;UseForDefaultRoute&gt;</code> section - not before.</p>
  
  <p>I've tried to do <code>InsertBefore()</code> and <code>InsertAfter()</code>, but it just doesn't want to work.
  Finally, when I do the <code>AppendChild()</code> approach, I also get a bit of extra text I wasn't expecting, something about xmlns?</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;IpRanges xmlns=""&gt;&lt;IpRange&gt;&lt;StartAddress&gt;1.2.3.5&lt;/StartAddress&gt;&lt;EndAddress&gt;1.2.3.5&lt;/EndAddress&gt;&lt;/IpRange&gt;&lt;/IpRanges&gt;
  </code></pre>
  
  <p>This is what I managed to put together, bear in mind that it's broken :(</p>
  
  <pre class="lang-bsh prettyprint-override"><code># load XML file
  [xml]$doc = $response
  
  # create node &lt;StartAddress&gt;
  $startNode = $doc.CreateNode('element', 'StartAddress', '')
  $start = $doc.CreateTextNode('1.2.3.5')
  $startNode.AppendChild($start) | Out-Null
  
  # create node &lt;EndAddress&gt;
  $endNode = $doc.CreateNode('element', 'EndAddress', '')
  $end = $doc.CreateTextNode('1.2.3.5')
  $endNode.AppendChild($end) | Out-Null
  
  # create node &lt;IpRange&gt; and append child nodes &lt;StartAddress&gt; and     &lt;EndAddress&gt;
  $ipRange = $doc.CreateNode('element', 'IpRange', '')
  $ipRange.AppendChild($startNode) | Out-Null
  $ipRange.AppendChild($endNode) | Out-Null
  
  # create node &lt;IpRanges&gt; and append child nodes &lt;IpRange&gt;
  $ipRanges = $doc.CreateNode('element', 'IpRanges', '')
  $ipRanges.AppendChild($ipRange) | Out-Null
  
  # append node &lt;IpRanges&gt; to node &lt;SubnetParticipation&gt;
  $subnetParticpation = $doc.EdgeGateway.Configuration.GatewayInterfaces.GatewayInterface[1].SubnetParticipation.AppendChild($ipRanges)
  </code></pre>
  
  <p>...following advice from Ansgar, this is my attempt at using a namespace. (broken)</p>
  
  <pre><code>[xml]$fragment = "&lt;dummy xmlns:xsi='http://www.vmware.com/vcloud/v1.5'&gt;&lt;IpRanges&gt;$($ipRanges.InnerXml)&lt;/IpRanges&gt;&lt;/dummy&gt;"
  
  # $fragment.InnerXml ..returns..
  # &lt;dummy xmlns:xsi="http://www.vmware.com/vcloud/v1.5"&gt;&lt;IpRanges&gt;&lt;IpRange&gt;&lt;StartAddress&gt;185.39.247.98&lt;/StartAddress&gt;&lt;EndAddress&gt;185.39.247.98&lt;/EndAddress&gt;&lt;/IpRange&gt;&lt;/IpRanges&gt;&lt;/dummy&gt;
  
  # $body is the full XML Document I want to paste into
  [xml]$xml = $body
  
  $nsm = New-Object Xml.XmlNamespaceManager $xml.NameTable
  $nsm.AddNamespace('xsi', $xml.NamespaceURI)
  $node = $xml.ImportNode($fragment.DocumentElement.IpRanges, $true)
  
  $subnetPart = $xml.SelectSingleNode("//IpAddress[text()='185.39.247.98']", $nsm)
  $subnetPart
  
  # returns nothing
  </code></pre>