Kristian Fenn
Kristian Fenn

Reputation: 867

Powershell adding characters in XML

I've got an XML file that's something like this:

<globalConfigs>
  <!-- some settings -->
  <globalConfig key="currency" value="£" />
</globalConfigs>

And I've got some Powershell which is manipulating it along the lines of this:

function Update-Config ($filePath, $siteName) {
    [xml]$config = Get-Content $filePath;
    $newNode = $config.CreateElement("globalConfig");

    $keyAttribute = $config.CreateAttribute("key");
    $keyAttribute.Value = "currencyCode";
    $newNode.Attributes.Append($keyAttribute);

    $valAttribute = $config.CreateAttribute("value");
    $valAttribute.Value = "GBP";
    $newNode.Attributes.Append($valAttribute);

    $config.globalConfigs.AppendChild($newNode);
    Write-Log "Added config node to site.";
    $config.Save($filePath);
}

Now this works as expected in that it adds the new key. But the resulting xml adds an extra character in before the pound sign:

<globalConfigs>
  <!-- some settings -->
  <globalConfig key="currency" value="£" />
  <globalConfig key="currencyCode" value="GBP" />
</globalConfigs>

What is causing this extra character? It appears to be intermittent, but it's added more often than not.

Upvotes: 3

Views: 585

Answers (2)

Kristian Fenn
Kristian Fenn

Reputation: 867

I managed to fix this - the issue is in the Get-Content cmdlet. If I change the line that loads the XML to this:

[xml]$config = Get-Content $filePath -Encoding UTF8;

then I don't get the unwanted character in the output.

Upvotes: 1

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200193

Your XML contains a non-ASCII character without proper encoding. Either encode the character as an entity reference (&#163;), or add a declaration to your XML data:

function Update-Config ($filePath, $siteName) {
    [xml]$config = Get-Content $filePath;
    $newNode = $config.CreateElement("globalConfig");

    $keyAttribute = $config.CreateAttribute("key");
    $keyAttribute.Value = "currencyCode";
    $newNode.Attributes.Append($keyAttribute);

    $valAttribute = $config.CreateAttribute("value");
    $valAttribute.Value = "GBP";
    $newNode.Attributes.Append($valAttribute);

    $config.globalConfigs.AppendChild($newNode)
    Write-Log "Added config node to site."
    $declaration = $config.CreateXmlDeclaration('1.0', 'utf-8', $null)
    [void]$config.InsertBefore($declaration, $config.DocumentElement)
    $config.Save($filePath)
}

Upvotes: 1

Related Questions