Powershell保存XML并保留格式

时间:2011-11-17 00:21:02

标签: powershell

我想读取XML文件并修改元素然后将其保存回文件。在保留格式的同时保持匹配行终止符(CRLF与LF)的最佳方法是什么?

这是我所拥有的,但它并没有这样做:

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

问题是在我混合了LF和CRLF之后,删除了额外的新行(也就是xml中的空行)。

感谢帮助推出PowerShell新手:)

5 个答案:

答案 0 :(得分:37)

您可以使用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)而不是属性

答案 1 :(得分:3)

如果要在XmlDocument上调用Save方法后更正为文本节点转换为LF的CRLF,则可以使用XmlWriterSettings实例。 使用与MilesDavies192s answer相同的XmlWriter,但也将编码更改为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 :(得分:2)

如果使用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)

答案 3 :(得分:0)

我看不到行尾有任何变化(\ r \ n),只是最后一行消失了。但是,使用BOM将编码从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

答案 4 :(得分:0)

读取xml时默认忽略空行,为了保留它们,您可以在读取文件之前更改PreserveWhitespace属性

创建 XmlDocument 对象并配置 PreserveWhitespace:

$xmlDoc = [xml]::new()
$xmlDoc.PreserveWhitespace = $true

加载文档:

$xmlDoc.Load($myFilePath)

$xmlDoc.LoadXml($(Get-Content $myFilePath -Raw))