I'm trying to add a new element in my xml file using powershell.
XML File (can't change the current content except adding a new element under Languages):
<UserSettings>
<ApplicationIdentity version="16.0" />
<Category name="License Header Manager_Languages" Category="{d1b5984c-1693-4f26-891e-0ba3bf5760b4}" Package="{4c570677-8476-4d33-bd0c-da36c89287c8}" RegisteredName="License Header Manager_Languages" PackageName="LicenseHeadersPackage">
<PropertyValue name="LanguagesSerialized"><Languages>
<Language LineComment="//" BeginComment="/*" EndComment="*/" BeginRegion="#region" EndRegion="#endregion" SkipExpression="">
<Extensions>
<Extension>.cs</Extension>
</Extensions>
</Language>
<Language LineComment="'" BeginComment="" EndComment="" BeginRegion="#Region" EndRegion="#End Region" SkipExpression="">
<Extensions>
<Extension>.vb</Extension>
</Extensions>
</Language>
</Languages>
</PropertyValue>
</Category>
</UserSettings>
I'm trying to add add a new language with different extensions using following code
$file = "C:\Users\TempUser\Downloads\CurrentSettings.xml"
[xml]$xml = Get-Content $file
$extensions = @(
,@( @("#", "<#", "#>", ""), @(".ps1", ".psm1"))
,@( @("//", "/*", "*/", ""), @(".js", ".ts")))
$AttributeNames = @("LineComment", "BeginComment", "EndComment", "SkipExpression")
$xml.UserSettings.Category.PropertyValue | Where-Object { $_.name -eq "LanguagesSerialized" } | %{
foreach ($elements in $extensions) {
$lang = $xml.CreateElement("Language")
for ($j=0; $j -lt $AttributeNames.length; $j++) {
$lang.SetAttribute($AttributeNames[$j], $elements[0][$j])
}
$extsElement = $lang.AppendChild($xml.CreateElement("Extensions"))
foreach($ext in $elements[1]){
$extElement = $extsElement.AppendChild($xml.CreateElement("Extension"))
$extElement.AppendChild($xml.CreateTextNode($ext))
}
$_.AppendChild($lang)
}
}
$xml.Save($file)
Expected result:
<Language LineComment="#" BeginComment="@*" EndComment="*@" BeginRegion="" EndRegion="" SkipExpression="">
<Extensions>
<Extension>.ps1</Extension>
<Extension>.psm1</Extension>
</Extensions>
</Language>
Current Output in file (It adds the elements after Languages Tag):
</Language>
</Languages><Language LineComment="#" BeginComment="<#" EndComment="#>" SkipExpression=""><Extensions><Extension>.ps1</Extension><Extension>.psm1</Extension></Extensions></Language><Language LineComment="//" BeginComment="/*" EndComment="*/" SkipExpression=""><Extensions><Extension>.js</Extension><Extension>.ts</Extension></Extensions></Language></PropertyValue>
<PropertyValue name="Version">3.0.3</PropertyValue>
</Category>
</UserSettings>
Appreciate any help, thanks!
Thanks, guys! In my case, I can't encode and save as <
and >
in the file as that is another parser's job. I have to add the language before it goes to this parser. Previously, I was adding the child element outside the main Languages node. Here's the updated solution which adds the child language node into the main Languages node.
$file = "C:\Users\TempUser\Downloads\CurrentSettings.xml"
[xml]$xml = Get-Content $file
$extensions = @(
,@( @("#", "<#", "#>", ""), @(".ps1", ".psm1"))
,@( @("//", "/*", "*/", ""), @(".js", ".ts")))
$AttributeNames = @("LineComment", "BeginComment", "EndComment", "SkipExpression")
$xml.UserSettings.Category.PropertyValue | Where-Object { $_.name -eq "LanguagesSerialized" } | %{
[xml]$Settings = $_.'#text'
foreach ($elements in $ExtensionDetails) {
$lang = $Settings.CreateElement("Language")
for ($j=0; $j -lt $AttributeNames.length; $j++) {
$lang.SetAttribute($AttributeNames[$j], $elements[0][$j])
}
$extsElement = $lang.AppendChild($Settings.CreateElement("Extensions"))
foreach($ext in $elements[1]){
$extElement = $extsElement.AppendChild($Settings.CreateElement("Extension"))
$extElement.AppendChild($Settings.CreateTextNode($ext))
}
$Settings.Languages.AppendChild($lang)
}
$_.'#text' = $Settings.InnerXml
}
$xml.Save($file)
the output is
...
...
</Language>
<Language LineComment="#" BeginComment="@*" EndComment="*@" SkipExpression="">
<Extensions>
<Extension>.ps1</Extension>
<Extension>.psm1</Extension>
</Extensions>
</Language>
<Language LineComment="//" BeginComment="/*" EndComment="*/" SkipExpression="">
<Extensions>
<Extension>.js</Extension>
<Extension>.ts</Extension>
</Extensions>
</Language>
</Languages>