.SelectSingleNode in Powershell script using xPath not working on extracting values from web.config file

29,886

Your XML file has a namespace:

<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">

so you need a namespace manager for SelectSingleNode (see section "Remarks"):

XPath expressions can include namespaces. Namespace resolution is supported using the XmlNamespaceManager. If the XPath expression includes a prefix, the prefix and namespace URI pair must be added to the XmlNamespaceManager.

Something like this should work:

$ns = New-Object System.Xml.XmlNamespaceManager($WebConfigXml.NameTable)
$ns.AddNamespace("ns", $WebConfigXml.DocumentElement.NamespaceURI)
$node = $WebConfigXml.SelectSingleNode("//ns:add[@key='SiteDomain']", $ns)
Share:
29,886
Michael McCarthy
Author by

Michael McCarthy

Michael McCarthy is a .NET developer with almost 20 years building web-based, business applications. He’s worked in the loan industry, the financial industry and the pharmaceutical industry. He currently works as a Senior C# Developer at ALMAC, where he just finished a two year, green-field project re-write of their clinical trial software using SOA, DDD and TDD. Over the past five years, he’s switched his efforts from “n-tier” development to utilizing an SOA-based, asynchronous and durable approach to building business software powered by NServiceBus. In those years, he’s transformed into a TDD advocate, has embraced the SOLID principles and has come to rely on FakeItEasy for its ease of use and flexible API while writing his unit tests. In his spare time, he loves keeping up to date on all things NServiceBus, DDD, MVC and TDD. Publications: FakeItEasy Succinctly (free PDF download) http://www.syncfusion.com/resources/techportal/details/ebooks/fakeiteasy Published 9/3/2015 Assisted in proofing rough drafts of Implementing Domain Driven Design (the “Red Book”) by Vaughn Vernon. Mentioned in Acknowledgement section: http://www.amazon.com/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577 Blog: http://www.michaelgmccarthy.com/ LinkedIn: https://www.linkedin.com/in/michaelgmccarthy GitHub: https://github.com/mgmccarthy

Updated on July 09, 2022

Comments

  • Michael McCarthy
    Michael McCarthy almost 2 years

    Okay, so here is the snippet of my web.config file:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <location path="." inheritInChildApplications="false">
    <connectionStrings>
    ...
    </connectionStrings>
    </location>
    <location path="." inheritInChildApplications="false">
    <appSettings>
    <!--IT Ops-->
    <add key="SomeOtherKey" value="SomeOtherValue" />
    <add key="SiteDomain" value="somedomain.com" />
    <add key="SomeOtherKey" value="SomeOtherValue" />
    ....
    </appSettings>
    </location>
    </configuration>
    

    What I'm trying to do is find the node using xPath via Powershell. A couple things to note about this XML file:

    there are multiple:

    <location path="." inheritInChildApplications="false"> 
    

    values in the xml file. They surround other nodes like etc...

    I can find and replace the connection string values successfully using this script

    $WebConfigFile = Join-Path $destination Web.config
    [xml]$WebConfigXml = Get-Content ($WebConfigFile)
    $WebConfigXml.configuration.location[2].connectionStrings.add | % { $_.connectionString = $_.connectionString -replace "some value", $sqlServerName }
    

    But when I go to replace the add key="SiteDomain" value using this script:

    $node = $WebConfigXml.configuration.location[3].appSettings.SelectSingleNode("add[@key = 'SiteDomain']")
    $node.value = "someValue"
    $WebConfigXml.Save($WebConfigFile)
    

    it does not work. The $node value in this case contains an empty string.

    I'm also trying just to read the node like this:

    $appSettingsSection = $WebConfigXml.configuration.location[3].appSettings;
    $existingSiteDomain = $appSettingsSection.SelectSingleNode("add[@key='SiteDomain']")
    

    And I'm still getting an empty string for the $existingSiteDomain value.

    I've looked at samples using SelectSingleNode and I can't quite seem to figure it out. Not too sure what I'm doing wrong.

    Thanks, Mike

  • Michael McCarthy
    Michael McCarthy almost 11 years
    Okay, I tried that, but now I'm getting an error from Powershell. It doesn't know XmlNamespaceManager is: "XmlNamespaceManager : The term 'XmlNamespaceManager' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.". I ran "$psversiontable.psversion" on the powershell command line and it says I have Powershell version 3.0 installed. Is this some type of versioning problem?
  • Michael McCarthy
    Michael McCarthy almost 11 years
    Okay, I amend my previous comment. It is now working. I think there was some other syntax issue in my script that was causing this error. The code you provided worked! Thanks so much. I'm new to Powershell and xPath, so I had no idea about this namespace issue.