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:)
Ответы
Ответ 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()
}