Replacing XML Node

Welcome Forums General PowerShell Q&A Replacing XML Node

This topic contains 7 replies, has 3 voices, and was last updated by

1 year, 9 months ago.

  • Author
  • #70382

    Points: 0
    Rank: Member

    I'm trying to write a script to replace a node on a single XML file. My XML example can be seen here:

    I'm assuming I need to first figure out how to remove the existing node, then add the new one... But I'm stuck on the removal. This is what I currently have:

    $path = "C:\Testing\File.xml"
    [xml]$servicefactoryconfig = gc $path
    $AuditOut = $servicefactoryconfig.SelectSingleNode("[.='Audit']")

    When I run this, Notepad++ is telling me the file has been edited, but there is no difference in the file. I am also seeing this error:

    You cannot call a method on a null-valued expression.
    At line:14 char:1
    + $AuditOut.parentnode.removeall()
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

    Anyone have any suggestions? Is there an easier way to just replace this instead of removing, saving, and adding?

  • #70402

    Points: 492
    Helping Hand
    Rank: Contributor

    You can try something like this:

    #original XML content
    [xml]$myXml = @"
    #Build an object with your values
    $config = @()
    $config += [pscustomobject]@{name="baseUrl";class="string";value="http://hostname/Website"}
    $config += [pscustomobject]@{name="servicePath";class="string";value="Audit/AuditASMX.asmx"}
    $config += [pscustomobject]@{name="timeout";class="int";value="120"}
    $config += [pscustomobject]@{name="policy";class="string";value="AuditServicePolicy"}
    #Select Node
    $element = $
    #Remove Node
    foreach ($item in $config) {
        $child = $myXML.CreateElement("parameter")
        $addName = $myXML.CreateAttribute("name")
        $addName.Value = $item.Name
        $addClass = $myXML.CreateAttribute("Class")
        $addClass.Value = $item.Class
        $addValue = $myXML.CreateAttribute("Value")
        $addValue.Value = $item.Value
        #Append to Add
    $myXML.Save(("{0}\myxml.xml" -f [environment]::GetFolderPath("Desktop")))
  • #70405

    Points: 24
    Team Member
    Rank: Member

    I think I found the problem. Your XPath was not valid and yes the previous node needs to be removed.
    What do you think about the following?

    • #70409

      Points: 0
      Rank: Member

      You sir, are a rock star! Worked like a charm! THANK YOU!!!

    • #70426

      Points: 0
      Rank: Member

      Daniel – upon further investigation, a number of my existing "add" nodes are missing the closing tag after I run the file. And they don't seem to be related in any way to what we're adding or removing. It's like the entire node is still there, it's just missing the /add at the end. Any idea what might cause that?

      Edit: I just looked over the file. It appears it removed the closing tag on any add node that does not have a child node. If there is a child node, the closing tag was not removed.

    • #70492

      Points: 0
      Rank: Member

      Upon further investigation, this appears to be working... I had started by making a backup of the file and changed the file type to *.original instead of *.xml. I then compared the changed file with the original... Apparently CompareIt doesn't like to display XML files properly. As soon as I changed the *.original to *.xml and compared 2 xml files, both files were identical.

      Thanks again for the help!

  • #70408

    Points: 0
    Rank: Member

    Thanks Rob – a couple of questions. Admitting this is still fairly new to me, but I'm looking this over trying to figure out where the file path to my xml file should be going in here...

    Also, I probably should have mentioned this, but there are many "add" nodes in this file, and this particular node can be in any location on the file. From the look of the code it's trying to remove the "first" add node. So it needs to be specific to the one that has the name "audit." So would I format that:

    $element.RemoveChild($element.add | where-object key -eq "audit")


  • #70411

    Points: 492
    Helping Hand
    Rank: Contributor

    Daniel showed an example using xpath to specify a certain element, this is more dot notation. Yes, you can specifically reference a child using a where clause like such:

    $element.RemoveChild(($element.parameter | Where{$_.value -like "*audit*"}))

The topic ‘Replacing XML Node’ is closed to new replies.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort