我想读取XML文件并修改元素然后将其保存回文件。在保留格式的同时保持匹配行终止符(CRLF与LF)的最佳方法是什么?
这是我所拥有的,但它并没有这样做:
$xml = [xml]([System.IO.File]::ReadAllText($fileName))
$xml.PreserveWhitespace = $true
# Change some element
$xml.Save($fileName)
问题是在我混合了LF和CRLF之后,删除了额外的新行(也就是xml中的空行)。
感谢帮助推出PowerShell新手:)
答案 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))