【问题标题】:How can I keep accents in xml file after editing it?编辑后如何在 xml 文件中保留重音符号?
【发布时间】:2020-11-26 04:58:03
【问题描述】:

我正在尝试修改 xml 配置文件中的一个属性值,但是当我保存它时,重音被替换:ô => ô

这是我的代码

    $xmlDoc = [XML](Get-Content "C:\MesInterface.config")
    $xmlDoc.configuration.ContrôleFlan.lastId = "0"
    $xmlDoc.Save("C:\MesInterface.config")

保存后会发生什么

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<ContrôleFlan lastId="0"/></configuration>

【问题讨论】:

  • 您的 PowerShell 代码肯定在 ps1 文件中。检查该 ps1 文件的编码是否为 UTF-8。
  • @MundoPeter 它已经是 UTF8 编码,我已经切换到 AINSI,现在我的 XML 是正确的。谢谢

标签: xml powershell diacritics


【解决方案1】:

一般建议是当涉及国际字符时,将.ps1 文件编码为 UTF-8使用 BOM 保存。

Powershell v5.1 及更早版本假定.ps1 文件没有Windows-1252 代码页中编码的 BOM(字节顺序标记)。来自doc page

当没有 BOM 时,PowerShell 5.1 及更低版本默认为 Windows-1252 编码。
出于互操作性原因,最好将脚本保存为带有 BOM 的 Unicode 格式。

[ EDIT ] 正如@mklement0 在评论中指出的那样(以及reported 给MS),上面引用的官方文档似乎是错误的。 PowerShell 默认为系统范围的默认 ANSI codepage,通常但不一定是 Windows-1252。 [结束编辑]

OP 在评论中写道:

[.ps1 文件] 已经是 UTF8 编码,我已经切换到 ANSI,现在我的 XML 是正确的

在这种情况下有效,因为字符 ô 恰好存在于 Windows-1252 (ANSI) 代码页中。

但是,将.ps1 文件保存为 ANSI 仍会导致它无法处理 Windows-1252 代码页之外的字符。例如,如果将以下内容复制/粘贴到使用 ANSI 编码保存的 .ps1 文件中将失败,但如果使用 BOM 保存为 UTF-8 则将起作用。

    $xmlDoc = [XML](Get-Content "C:\MesInterface.config")
    $xmlDoc.configuration.ContrôleFlan.lastId = "αß©∂€"
    $xmlDoc.Save("C:\MesInterface.config")

【讨论】:

    【解决方案2】:

    有两个最终独立的方面需要考虑:

    • 如果您的脚本文件本身包含(与代码相关的)非 ASCII 字符,例如 ô,您必须确保 PowerShell 引擎正确解释它们。

      • 最安全的选择是使用 UTF-8 编码带有 BOM 保存您的 *.ps1 文件(带有 BOM 的 UTF-16 也是一种选择,但对于主要包含 ASCII 范围的字符):它确保两个 PowerShell 版本(Windows PowerShell 和 PowerShell [Core] v6+)都能正确读取文件,并且可以表示所有 Unicode 字符。
    • 由于您的 XML 文档有一个指定其编码的 XML 声明 - encoding="utf-8" - 您应该遵从 .NET 的 XML API 来识别文档时的编码从文件中读取,并在写回文件时。

      • 通过使用.Save() 方法,您已经在将文档写入回文件时推迟到API,但是使用Get-Content - 它对XML 一无所知 - 对于reading 表示文件可能被误解;具体来说,在没有 UTF-8 BOM 的情况下,Windows PowerShell 会将文件读取为 ANSI 编码(但请注意,PowerShell [Core] v6+ 现在明智地默认为 UTF-8)。

      • 因此,使用[xml] 类型的.Load() 方法而不是Get-Content 来读取文件,该方法尊重XML 声明中指定的编码:

    $file = 'C:\MesInterface.config'
    
    $xmlDoc = New-Object xml
    
    $xmlDoc.Load($file)
    
    $xmlDoc.configuration.ContrôleFlan.lastId = "0"
    
    $xmlDoc.Save($file)
    

    【讨论】:

      【解决方案3】:

      如果你想在代码中为你的 XML 设置编码,你可以这样做:

      $settings = New-Object System.Xml.XmlWriterSettings
      $settings.Encoding = [System.Text.Encoding]::Unicode
      
      $writer = [System.Xml.XmlWriter]::Create("c:\test\mydata.xml", $settings);
      
      $xmlDoc.Save($writer)
      
      $writer.Close()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-26
        • 2012-01-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多