PowerShell XML保留缩进

时间:2018-06-27 20:53:57

标签: xml powershell

我是PowerShell的新手,并试图编写一个脚本来编辑XML文件,方法是根据行是否存在来简单地添加和删除(该部分仍然丢失)。 但是,我已经成功地将线添加到正确的位置。但是添加行后保存xml时,缩进以某种方式被破坏/转换为2个空格。 $ xml.PreserveWhiteSpace = $ true通过删除所有换行符来完全破坏格式。 我还尝试了XmlWriter,该文件似乎在后台崩溃,阻止了文件的进一步编辑,直到下次重新启动。

这是我原始的xml内容:

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Application>
        <LastUsedFile>
            <Path></Path>
            <CredProtMode>Obf</CredProtMode>
            <CredSaveMode>NoSave</CredSaveMode>
        </LastUsedFile>
    </Application>
</Configuration>

它应该是这样的样子(LastUsedFile之前的新元素LanguageFile):

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <Application>
        <LanguageFile>German.lngx</LanguageFile>
        <LastUsedFile>
            <Path></Path>
            <CredProtMode>Obf</CredProtMode>
            <CredSaveMode>NoSave</CredSaveMode>
        </LastUsedFile>
    </Application>
</Configuration>

这是我保存后实际收到的:

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Application>
    <LanguageFile>German.lngx</LanguageFile>
    <LastUsedFile>
      <Path></Path>
      <CredProtMode>Obf</CredProtMode>
      <CredSaveMode>NoSave</CredSaveMode>
    </LastUsedFile>
</Configuration>

使用该代码购买:

$path = "$env:APPDATA\App"
$file = "$env:APPDATA\App\App.config.xml"
$NodeExists = $null

if ([System.IO.Directory]::Exists($path))
    {
        Write-Output "$path existiert."
        if ([System.IO.File]::Exists($file))
            {
                Write-Output "$file existiert."
                $xml = [XML](Get-Content $file)
                $application = $xml.Configuration.Application
                $NodeExists = $xml.Configuration.Application.LanguageFile
                Write-Output $NodeExists
                if(!$NodeExists)
                    {
                        $langelem = $xml.CreateElement('LanguageFile')
                        $langtext = $xml.CreateTextNode('German.lngx')
                        $langelem.AppendChild($langtext)
                        $application.InsertBefore($langelem, $application.FirstChild)
                        Write-Output "Sprache auf Deutsch gestellt."
                    }
                else
                    {
                        Write-Output "Sprache ist auf Deutsch gesetzt."
                        $application.RemoveChild($application.FirstChild)
                        Write-Output "Sprache auf Englisch gestellt."                       
                    }
                $xml.Save($file)
            }
        else
            {
                Write-Output "$file existiert NICHT."
            }
    }
else
    {
        Write-Output "$path existiert NICHT."
    }

1 个答案:

答案 0 :(得分:0)

@LotPings的评论提示that function提出了解决方案。添加

$xmlWriter.IndentChar = "`t"

该功能完全恢复了xml的原始格式。因此,现在更像是恢复缩进,而不是首先保留缩进。这是完整的工作代码,包括以下功能:

$path = "$env:APPDATA\App"
$file = "$env:APPDATA\App\App.config.xml"
$NodeExists = $null

Function Format-XMLIndent
{
    [Cmdletbinding()]
    [Alias("IndentXML")]
    param
    (
        [xml]$Content,
        [int]$Indent
    )

    # String Writer and XML Writer objects to write XML to string
    $StringWriter = New-Object System.IO.StringWriter 
    $XmlWriter = New-Object System.XMl.XmlTextWriter $StringWriter 

    # Default = None, change Formatting to Indented
    $xmlWriter.Formatting = "indented" 

    # Gets or sets how many IndentChars to write for each level in 
    # the hierarchy when Formatting is set to Formatting.Indented
    $xmlWriter.Indentation = $Indent
    $xmlWriter.IndentChar = "`t"

    $Content.WriteContentTo($XmlWriter) 
    $XmlWriter.Flush();$StringWriter.Flush() 
    $StringWriter.ToString()
}

if ([System.IO.Directory]::Exists($path))
    {
        Write-Output "$path existiert."
        if ([System.IO.File]::Exists($file))
            {
                Write-Output "$file existiert."
                $xml = [XML](Get-Content $file)
                $application = $xml.Configuration.Application
                $NodeExists = $xml.Configuration.Application.LanguageFile
                Write-Output $NodeExists
                if(!$NodeExists)
                    {
                        $langelem = $xml.CreateElement('LanguageFile')
                        $langtext = $xml.CreateTextNode('German.lngx')
                        $langelem.AppendChild($langtext)
                        $application.InsertBefore($langelem, $application.FirstChild)
                        Write-Output "Sprache auf Deutsch gestellt."
                    }
                else
                    {
                        Write-Output "Sprache ist auf Deutsch gesetzt."
                        $application.RemoveChild($application.FirstChild)
                        Write-Output "Sprache auf Englisch gestellt."                       
                    }
                IndentXML -Content $xml -Indent 1 | Set-Content $file -Encoding Utf8
            }
        else
            {
                Write-Output "$file existiert NICHT."
            }
    }
else
    {
        Write-Output "$path existiert NICHT."
    }