Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating XML files using PowerShell

Tags:

powershell

xml

I'm using PowerShell to update an XML directory listing for an application across a number of servers but having an issue making the actual updates. Using the following XML as an example, looking to update the filepaths with qualnas1 to use something like \GlobalNAS...etc and remove the qualnas2 entry.

<?xml version="1.0" encoding="UTF-8" ?>
<directory>
    <filepath>\\qualnas1\library\content</filepath>
    <filepath>\\qualnas2\library\content</filepath>
    <filepath type="sssb">\\qualnas1\SSSB\content</filepath>
</directory>

The filepath node with type=sssb works when I use the $_.InnerText, but can not find a way to update or remove the other nodes. Here is my code:

$DirectoryXMLPath = 'C:\Temp\directory.xml'
if (Test-Path $DirectoryXMLPath)
{
    $DirectoryXML = New-Object XML
    $DirectoryXML.Load($DirectoryXMLPath)
    $DirectoryXML.PreserveWhitespace = $true

    # Find qualnas1 path and replace with GlobalNAS
    $DirectoryXML.directory.filepath | Where-Object { $_ -eq '\\qualnas1\library\content' } | 
        ForEach-Object { $_.InnerText = '\\GlobalNAS\library\content' }

    # Find extraneous library paths and remove them
    $DirectoryXML.directory.filepath.Remove('\\qualnas2\library\content')
#   $DirectoryXML.directory.mountpoint | Where-Object { $_ -eq '\\qualnas2\library\content' } |
#       ForEach-Object { $DirectoryXML.RemoveChild($_) }

    # This line is good!  Need InnerText as attribute type exists
    $DirectoryXML.directory.filepath | Where-Object { $_.InnerText -eq '\\qualnas1\SSSB\content' } | 
        ForEach-Object { $_.InnerText = '\\GlobalNAS\SSSB\content' }
}

If I step through the code using PowerGUI each node is found and the replace/remove is attempted as I'd expect, but either get errors (string to XmlElement conversion) or no errors but no updates either depending on how I do assignment. Anyway to change/remove specific nodes if there are no attributes as in the SSSB example?

like image 569
AndyDrav Avatar asked Feb 10 '12 21:02

AndyDrav


1 Answers

I would use a little Xpath to get a handle to the XML nodes. To me it's easier than using the properties that PowerShell creates for XML nodes.

# Find qualnas1 path and replace with GlobalNAS
$DirectoryXML.SelectNodes('/directory/filepath') | ? {
        $_.InnerText -eq '\\qualnas1\library\content'
    } | % {
        $_.InnerText = '\\GlobalNAS\library\content'
    }

# Find extraneous library paths and remove them
$DirectoryXML.SelectNodes('/directory/filepath') | ? {
        $_.InnerText -eq '\\qualnas2\library\content'
    } | % {
        $_.ParentNode.RemoveChild($_)
    }
like image 187
Andy Arismendi Avatar answered Oct 24 '22 11:10

Andy Arismendi