Показать сообщение отдельно
Старый 09.01.2006, 12:14   #1  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Файлы XML, CSV, HTML в кодировке Unicode
Думаю, многим окажутся полезны мои изыскания в области представления текстовых данных в разных кодировках. Итак, задача: сгенерировать из Аксапта файл 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-файлы в кодировках, отличных от "родной", не умеет. По крайней мере, без дополнительных доработок.

Последний раз редактировалось EVGL; 09.01.2006 в 17:21.
За это сообщение автора поблагодарили: mazzy (18), belugin (14), kashperuk (1), zinius (1), alex55 (1), mix2ra (1).