PowerShell XML сохраняет отступ - PullRequest
0 голосов
/ 27 июня 2018

Я новичок в 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>

Вот как это должно выглядеть (новый элемент LanguageFile перед LastUsedFile):

<?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 голосов
/ 28 июня 2018

Комментарий @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."
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...