Powershell保存XML并保留格式

byqmnocz  于 2023-04-12  发布在  Shell
关注(0)|答案(5)|浏览(130)

我想读取一个XML文件并修改一个元素,然后将其保存回文件。在保持格式的同时保持行结束符匹配(CRLF vs LF)的最佳方法是什么?
这是我的,但它没有做到这一点:

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

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

uyhoqukh

uyhoqukh1#

您可以使用PowerShell [xml]对象并设置$xml.PreserveWhitespace = $true,或者使用.NET XmlDocument执行相同的操作:

# NOTE: Full path to file is *highly* recommended
$f = Convert-Path '.\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.PreserveWhitespace = $true
#$xml.psbase.PreserveWhitespace = $true  # Older PS versions

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

调用XmlDocument.LoadXmlDocument.LoadXml之前,请确保设置PreserveWhitespace

注意:这不会保留XML属性之间白色!* XML属性中的空白 * 似乎会保留,但 * 之间的空白 * 不会保留。文档中提到保留“空白节点”(node.NodeType = System.Xml.XmlNodeType.Whitespace),而不是属性

1hdlvixo

1hdlvixo2#

如果您希望更正在XmlDocument上调用保存方法后转换为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()
}
jdgnovmf

jdgnovmf3#

阅读xml时默认忽略空行,为了保留空行,可以在读取文件前修改PreserveWhitespace属性
创建XmlDocument对象并配置PreserveWhitespace:

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

加载文档:

$xmlDoc.Load($myFilePath)

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

1aaf6o9v4#

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

rjzwgtxy5#

我没有看到行尾改变(\r\n),除了最后一个消失。然而,编码从ASCII变成了带有BOM的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

相关问题