Powershell, сохраняющий XML и сохраняющий формат - PullRequest
22 голосов
/ 17 ноября 2011

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

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

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

Проблема в том, что лишние новые строки (также называемые пустыми строками в xml) удаляются, и после того, как я смешал LF и CRLF.

Спасибо за помощь новичку PowerShell :)

Ответы [ 4 ]

37 голосов
/ 17 ноября 2011

Вы можете использовать объект 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)

Просто убедитесь, что вы установили PreserveWhitespace передвызов XmlDocument.Load или XmlDocument.LoadXml.

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

3 голосов
/ 06 января 2018

Если вы хотите исправить CRLF, который преобразуется в LF для текстовых узлов после вызова метода Save в XmlDocument, вы можете использовать экземпляр XmlWriterSettings.Использует тот же XmlWriter, что и MilesDavies192s answer , но также изменяет кодировку на 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()
}
2 голосов
/ 13 января 2016

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

    $fileXML = New-Object System.Xml.XmlDocument

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

    $writerXML = [System.Xml.XmlWriter]::Create($file)
    $fileXML.Save($writerXML)
0 голосов
/ 07 ноября 2018

Я не вижу изменения концов строк (\ r \ n), за исключением последнего.Тем не менее, кодировка идет от ASCII до UTF8 с спецификацией.

$a = get-content -raw file.xml
$a -replace '\r','r' -replace '\n','n'

<?xml version="1.0" encoding="utf-8"?>rn<Configuration>rn  <ViewDefinitions />rn</Configuration>rn

[xml]$b = get-content file.xml
$b.save('file.xml')

$a = get-content -raw file.xml
$a -replace '\r','r' -replace '\n','n'

<?xml version="1.0" encoding="utf-8"?>rn<Configuration>rn  <ViewDefinitions />rn</Configuration>

# https://gist.github.com/jpoehls/2406504
get-fileencoding file.xml

UTF8
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...