PowerShell XML保留缩进

PowerShell XML保留缩进,xml,powershell,Xml,Powershell,我是PowerShell新手,尝试编写一个脚本,通过简单地添加和删除(该部分仍然缺失)来编辑xml文件,具体取决于行是否已经存在。 但我已经成功地将该行添加到正确的位置。但是在添加行后保存xml时,缩进不知何故被打断/转换为2个空格。 $xml.PreserveWhiteSpace=$true通过删除所有换行符完全中断格式设置。 我还尝试了XmlWriter,它似乎在后台崩溃,阻止了文件的进一步编辑,直到下次重新启动 以下是我的原始xml内容: <?xml version="1.0" en

我是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>

来自@LotPings的带有提示的注释带来了解决方案。添加

$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."
    }

为什么XML是缩进2个空格还是4个空格都很重要?@AnsgarWiechers的观点很好。Eddga如果是为了美学,请看@AnsgarWiechers,我想不是,但我想尽量保持文件的原始状态。不知道这种转换是否会破坏使用此配置的程序的功能。除此之外,我更可能会问为什么脚本会导致这个问题?@LotPings我如何使用该脚本进行保存?看起来像是要与控制台一起使用?(再一次:对不起,我是PS新手)这是一个函数,你向它提供什么,你对输出做什么取决于你,把它放到evt的地方。要
|设置Content file.xml-编码Utf8
$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."
    }
$xmlWriter.IndentChar = "`t"
$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."
    }