XML to console using StringWriter expanding variables rather than writing strings literally\
I have been using this function to dump XML to the console for review as I work on code to do some extensive XML manipulation, and for the most part it works as expected.
function Write-PxXmlToConsole {
param (
[Xml.XmlNode]$Xml
)
if ($Xml -is [Xml.XmlDocument]) {
$xmlDocument = $Xml
} else {
$xmlDocument = [Xml.XmlDocument]::new()
$newElement = $xmlDocument.ImportNode($Xml, $True)
[Void]$xmlDocument.AppendChild($newElement)
}
$stringWriter = [System.IO.StringWriter]::new()
$xmlWriter = [System.Xml.XmlTextWriter]::new($stringWriter)
$xmlWriter.Formatting = "indented"
$xmlDocument.WriteTo($xmlWriter)
$xmlWriter.Flush()
$stringWriter.Flush()
Write-Host $stringWriter.ToString()
Write-Host
}
However, it seems that somewhere in the [System.IO.StringWriter]
variables are getting expanded. Because when my XML looks like this
$xml = [Xml]@"
<Pattern>$key.Value</Pattern>
"@
Write-PxXmlToConsole $xml
I get <Pattern>Autodesk Revit 2019.Value</Pattern>
as output because somewhere in this session the variable $key
got populated. And if I start a new session I will get <Pattern>.Value</Pattern>
. A bit of a pain, and I can't seem to find anything here that suggests a setting that would suppress this behavior.
Answers
The issue you're encountering is due to variable expansion within strings in PowerShell. When you write $key.Value
inside a double-quoted string, PowerShell tries to substitute the value of $key
followed by .Value
. If $key
is defined in your session, it will be replaced with its value.
To prevent this behavior, you can use single quotes instead of double quotes around your XML string. Single quotes prevent variable expansion in PowerShell.
Here's how you can modify your XML creation to use single quotes:
$xml = [Xml]@'
<Pattern>$($key.Value)</Pattern>
'@
Using single quotes will ensure that $key.Value
is treated as a literal string within the XML, and it won't be replaced with the value of $key
during variable expansion.
Alternatively, if you need to use double quotes for some reason and want to prevent variable expansion, you can escape the $
character using a backtick (`).
$xml = [Xml]@"
<Pattern>`$key.Value</Pattern>
"@
This way, PowerShell treats $key.Value
as a literal string without trying to replace it with the value of $key
.