Как сохранить акценты в файле xml после его редактирования? - PullRequest
3 голосов
/ 06 августа 2020

Я пытаюсь изменить одно значение атрибута в файле конфигурации 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>

Ответы [ 3 ]

2 голосов
/ 06 августа 2020

Необходимо учитывать два совершенно независимых аспекта:

  • Если ваш файл сценария содержит (относящиеся к коду) символы, отличные от ASCII, такие как ô, вы должны убедиться, что Механизм PowerShell интерпретирует их правильно.

    • Самый безопасный вариант - сохранить файлы *.ps1 в кодировке UTF-8 с спецификацией (UTF-16 со спецификацией также является вариантом, но расточительным для файлов, которые в основном содержат символы диапазона ASCII): он гарантирует, что обе версии PowerShell (Windows PowerShell и PowerShell [Core] v6 +) правильно прочитают файл и что все символы Unicode могут быть
  • Поскольку ваш XML документ имеет объявление XML, которое определяет его кодировку - encoding="utf-8" - вам следует отложить до. NET XML API для распознавания кодировки как при чтении документа из файла, так и при его записи обратно в файл.

    • Автор используя метод .Save(), вы уже dy откладывание на API при записи документа обратно в файл, но использование Get-Content - который ничего не знает о XML - для чтения означает, что файл может получить неверно истолкованный; в частности, при отсутствии спецификации UTF-8 Windows PowerShell будет читать файл как в кодировке ANSI (но обратите внимание, что PowerShell [Core] v6 + теперь разумно по умолчанию использует UTF-8).

    • Поэтому вместо Get-Content используйте метод [xml] type .Load() для чтения файла, который соблюдает кодировку, указанную в объявлении XML. :

$file = 'C:\MesInterface.config'

$xmlDoc = New-Object xml

$xmlDoc.Load($file)

$xmlDoc.configuration.ContrôleFlan.lastId = "0"

$xmlDoc.Save($file)
1 голос
/ 06 августа 2020

Общий совет - сохранить файл .ps1 в кодировке UTF-8 с спецификацией , когда задействованы международные символы.

Powershell v5.1 и ранее предполагалось, что .ps1 файлы без спецификации (метка порядка байтов) должны быть закодированы в кодовой странице Windows -1252 . На странице do c :

PowerShell 5.1 и ниже по умолчанию используется кодировка Windows -1252, когда нет спецификации.
Из соображений совместимости лучше всего сохранять скрипты в формате Unicode с BOM.

[ EDIT ] Официальная документация, приведенная выше, кажется неправильной, как указано @ mklement0 в комментарии (и сообщил в MS). PowerShell по умолчанию использует общесистемную кодовую страницу ANSI , вместо этого, часто, но не обязательно, Windows -1252. [ конец EDIT ]

OP написал в комментарии:

[ файл .ps1 ] уже был UTF8 закодировано, я переключился на ANSI, и теперь мой XML правильный

Это сработало в этом случае , потому что символ ô существует в Windows -1252 (ANSI) кодовая страница.

Однако сохранение файла .ps1 как ANSI по-прежнему приведет к сбою для символов вне кодовой страницы Windows -1252. Например, следующее не удастся, если скопировать / вставить в файл .ps1, сохраненный с кодировкой ANSI, но будет работать, если будет сохранен как UTF-8 с спецификацией.

    $xmlDoc = [XML](Get-Content "C:\MesInterface.config")
    $xmlDoc.configuration.ContrôleFlan.lastId = "αß©∂€"
    $xmlDoc.Save("C:\MesInterface.config")
0 голосов
/ 06 августа 2020

Если вы хотите установить кодировку в коде для своего 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()
...