Невозможно поддерживать символы, отличные от UTF-8, в файле XML, созданном с помощью ColdFusion - PullRequest
2 голосов
/ 13 июля 2020

Когда я запускаю следующий код на сервере под управлением ColdFusion 2018:

<cfsetting enablecfoutputonly="yes">

<cfxml variable="test">
    <cfoutput>
        <test>
            áéíóú
        </test>
    </cfoutput>
</cfxml>

<cfset testString = ToString(test)>

<cfset testStringISO = Replace(testString, "UTF-8", "iso-8859-1")>

<cffile action="write" file="#AbsoluteFilesPath#test.xml" output="#testStringISO#" charset="iso-8859-1">

Где AbsoluteFilesPath - это абсолютная ссылка на расположение на сервере. Метод, который я использую для изменения кодировки XML, находится здесь . Файл test.xml выглядит так, когда я открываю его на сервере в Notepad ++:

<?xml version="1.0" encoding="iso-8859-1"?>
<test>
    αινσϊ
</test>

Кодировка файла отображается как «ISO 8859-7».

Интересно, открытие файл с VSCode на моем локальном компьютере отображается следующим образом:

<?xml version="1.0" encoding="iso-8859-1"?>
<test>
    �����
</test>

Здесь кодировка файла отображается как «UTF-8». Выбор команды «Открыть заново с кодировкой ISO 8859-1» в редакторе показывает файл таким, каким он должен быть:

<?xml version="1.0" encoding="iso-8859-1"?>
<test>
    áéíóú
</test>

Я протестировал этот код, заменив «iso-8859-1» на «utf». -16 ", и результаты такие же.

Почему кодировка файла не соответствует моим ожиданиям? Как я могу гарантировать, что файл создан с правильной кодировкой?

1 Ответ

4 голосов
/ 13 июля 2020

Давайте сначала кое-что проясним: атрибут encoding в файле XML - всего лишь индикатор для читателя. Это не влияет на количество байтов, записанных в фактический файл.

Итак, давайте упростим пример кода до одного символа á:

image á

Результирующие файлы

UTF-8. xml

utf

ISO-8859-1.xml

iso

This is exactly what we expected. Neither cfxml nor cffile/fileWrite is the issue. So how come you might not get the same result with the above code on your machine?

The problem: Page encoding

When ColdFusion parses template files (.cfm) and component files (.cfc), it will use the JVM's default encoding, which, unless specified otherwise, is the system's default encoding. This is also the reason, why everyone can get different results with the above code.

If you have a literal such as á in a file, this character is encoded using whatever you told your text editor to use. Let's assume that's UTF-8. If you inspect the file, you will see that the character is properly stored. However, when ColdFusion opens this file and parses the literal, it will assume the character to be encoded with the system's default encoding. And unfortunately you seem to run a system that doesn't or cannot use UTF-8 as systemwide codeset (Windows for example).

Solutions

An (ugly) way to solve it

cfprocessingdirective

(Хакерский) способ решить эту проблему

Сохраните каждый файл, которого ColdFusion затрагивает своим парсером (все .cfm / .cfc файлы), как UTF-8 с BOM . Когда ColdFusion встречает эти байты в начале файла, он вынужден использовать UTF-8, потому что это подразумевает спецификация.

Глобальный способ решения

Добавить -Dfile.encoding=UTF-8 в ваш ColdFusion JVM. Здесь можно добавить параметр: /cfusion/bin/jvm.config (строка: java.args=)

Для этого требуется перезапуск ColdFusion. Затем все ваши файлы можно сохранить как простой UTF-8 (без спецификации), и он будет работать нормально.

...