Думаю, многим окажутся полезны мои изыскания в области представления текстовых данных в разных кодировках. Итак, задача: сгенерировать из Аксапта файл CSV в кодировке UTF-16.
Одно из решений - это создать промежуточный файл XML в "родной" кодировке Аксапта, а затем с помощью XSL-шаблона превратить его в CSV в соответствующей кодировке.
Это достигается следующим выражением xsl:
PHP код:
<xsl:output encoding="UTF-16" />
при условии, что в processing instructions XML-файла задана исходная "родная" для Аксапта кодировка:
<?xml version="1.0" encoding="ISO-8859-2"?> (это для Польши, Венгрии и других восточноевропейских стран, использующих латинский алфавит).
А вот полный текст простого шаблона, который позволяет изменить кодировку XML-файла на желаемую:
PHP код:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="no" method="xml" media-type="text/xml"
indent="no" encoding="UTF-16" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Подробно все рассказано в статье
XML Encoding and DOM Interface Methods.
При этом в Аксапта запустить XSL-шаблон на исполнение, на первый взгляд, исключительно просто:
PHP код:
xmlString = xmlDocument.transformNode(_xsltDocument)
где функции transformNode передается класс XMLDocument с загруженным XSL-шаблоном, в ответ она возващает результат преобразования в виде строки.
Просто? Не тут-то было. Аксапта, как известно, продукт на чрезвычайно совеременной технологической платформе, и со строками Unicode работать не умеет.
По-видимому, уже в момент приема строки-результата из компонента Msxml2.DOMDocument Аксапта преобразовывает результат из Unicode обратно в "родную" 8-битную кодировку.
Рекомендованное решение - использовать не метод transformNode(), а метод transformNodeToObject(), который способен писать прямо в поток ADODB.Stream, т.е. писать результат на диск в обход Аксапта. Если разработать простой класс-обертку для ADODB.Stream, то код в Аксапта может выглядеть так:
PHP код:
outputStream = new ADODBStream();
outputStream.type(1); // binary
outputStream.open();
_outputDocument.com().transformNodeToObject(_xsltDocument.com(),
outputStream.com());
outputStream.saveToFile(outputFileNameFull);
outputStream.close();
Все! Осталось заметить, что по вышеуказанным причинам модуль Commerce Gateway сохранять XML-файлы в кодировках, отличных от "родной", не умеет. По крайней мере, без дополнительных доработок.