简体   繁体   中英

Inserting a new node into XML with PowerShell

I have an XML schema that I'm trying to insert new nodes into:

<clusters>
  <cluster>
    <name>
      cfcluster
    </name>
    <port>
      45564
    </port>
    <sessionreplication>
      true
    </sessionreplication>
    <server>
      cfusion1
    </server>
    <server>
      cfusion2
    </server>
    <stickysession>
      true
    </stickysession>
  </cluster>
</clusters>

I'm trying to write a script that has a new sever value, will check it against existing ones, then insert the new one after existing ones if it isn't found. Say for example I have a new server value cfusion3, I'd want my new output to end up like this:

<clusters>
  <cluster>
    <name>
      cfcluster
    </name>
    <port>
      45564
    </port>
    <sessionreplication>
      true
    </sessionreplication>
    <server>
      cfusion1
    </server>
    <server>
      cfusion2
    </server>
    <server>
      cfusion3
    </server>
    <stickysession>
      true
    </stickysession>
  </cluster>
</clusters>

Assuming I have the xml stored in $clusterData and the new server I want to insert is stored in $cfInstance.name, I was thinking I'd use something like this, but can't get it working...

if (-not ($clusterData.clusters.cluster.server -match $cfInstance.name)) {
    $oldServer = ($clusterData | Select-Xml '/clusters/cluster/server').get_node()
    $newServer = $clusterData.CreateElement("server")
    $newServer.InnerText = $cfInstance.name
    $clusterData.InsertAfter($newServer, $oldServer)
}

I'm pretty sure the problem is that $oldServer is getting all <server> nodes and I'm not sure how to modify the xpath to get just one. I've tried:
Select-Xml -Xml $clusterData -XPath "clusters/cluster/server[text()='cfusion2']"
but that doesn't return anything. Any suggestions?

Use the following XPath to return only the last existing server element :

/clusters/cluster/server[last()]

/clusters/cluster/server[text()='cfusion2'] didn't work possibly because the inner text of the corresponding server element isn't exactly equals to "cfusion2" . There are white-spaces that you didn't consider. Try using normalize-space() to clean up unnecessary white-spaces before doing comparison, like so :

/clusters/cluster/server[normalize-space()='cfusion2']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM