Подтвердить что ты не робот

Powershell сохраняет XML и сохраняет формат

Я хочу прочитать в файле XML и изменить элемент, а затем сохранить его обратно в файл. Каков наилучший способ сделать это, сохраняя формат, а также поддерживая соответствие терминатора линии (CRLF vs LF)?

Вот что у меня есть, но он этого не делает:

$xml = [xml]([System.IO.File]::ReadAllText($fileName))
$xml.PreserveWhitespace = $true
# Change some element
$xml.Save($fileName)

Проблема заключается в том, что Extra new Lines (aka empty lines in xml) удаляются и после того, как у меня смешанные LF и CRLF.

Спасибо, что помог новичкам PowerShell:)

4b9b3361

Ответ 1

Вы можете использовать объект PowerShell [xml] и установить $xml.PreserveWhitespace = $true или сделать то же самое с помощью .NET XmlDocument:

$f = '.\xml_test.xml'

# Using .NET XmlDocument
$xml = New-Object System.Xml.XmlDocument
$xml.PreserveWhitespace = $true

# Or using PS [xml] (older PowerShell versions may need to use psbase)
$xml = New-Object xml
#$xml.psbase.PreserveWhitespace = $true  # Older PS versions
$xml.PreserveWhitespace = $true

# Load with preserve setting
$xml.Load($f)
$n = $xml.SelectSingleNode('//file')
$n.InnerText = 'b'
$xml.Save($f)

Просто перед установкой XmlDocument.Load или XmlDocument.LoadXml установите PreserveWhitespace.

ПРИМЕЧАНИЕ. Это не сохраняет пробел между атрибутами XML! Белое пространство в XML-атрибутах, похоже, сохраняется, но не между ними. В документации говорится о сохранении "белых пробелов узлов" (node.NodeType = System.Xml.XmlNodeType.Whitespace), а не атрибутов.

Ответ 2

Если вы сохраняете с помощью XmlWriter, то по умолчанию параметры имеют отступ с двумя пробелами и заменяют окончания строки CR/LF. Вы можете настроить эти параметры после создания записи или создать запись с объектом XmlSettings, настроенным с учетом ваших потребностей.

    $fileXML = New-Object System.Xml.XmlDocument

    # Try and read the file as XML. Let the errors go if it not.
    [void]$fileXML.Load($file)

    $writerXML = [System.Xml.XmlWriter]::Create($file)
    $fileXML.Save($writerXML)

Ответ 3

Если вы хотите исправить CRLF, который преобразуется в LF для текстовых узлов после вызова метода Save на XmlDocument, вы можете использовать экземпляр XmlWriterSettings. Использует тот же XmlWriter как ответ MilesDavies192s, но также изменяет кодировку на utf-8 и сохраняет отступы.

$xml = [xml]([System.IO.File]::ReadAllText($fileName))
$xml.PreserveWhitespace = $true

# Change some element

#Settings object will instruct how the xml elements are written to the file
$settings = New-Object System.Xml.XmlWriterSettings
$settings.Indent = $true
#NewLineChars will affect all newlines
$settings.NewLineChars ="`r`n"
#Set an optional encoding, UTF-8 is the most used (without BOM)
$settings.Encoding = New-Object System.Text.UTF8Encoding( $false )

$w = [System.Xml.XmlWriter]::Create($fileName, $settings)
try{
    $xml.Save( $w )
} finally{
    $w.Dispose()
}