AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 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).
Старый 09.01.2006, 12:36   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Спасибо. Добавил респект.
__________________
полезное на axForum, github, vk, coub.
Старый 25.09.2008, 17:26   #3  
zinius is offline
zinius
Участник
 
24 / 11 (1) +
Регистрация: 26.01.2005
Thumbs up
Добавлю готовый тестовый джоб, для экономии времени желающим что-нибудь выгрузить в нетрадиционной кодировке из Ax 3.0

Задача - выгрузить набор текстовых строк из аксапты в файл нужной кодировки.

кодировка указывается в define, в моём случае это ISO-8859-5
(ключевые слова UTF-8, UTF-16 и прочий unicode)

X++:
#define.FILE('FILE')
#define.LINE('LINE')
#define.codePage('ISO-8859-5')
#define.fileFullName(@'D:\testXML_ISO.txt')
static void Test_XML2ISO(Args _args)
{
    XMLDocument doc = XMLDocument::newBlank();
    XMLElement  file = doc.createElement(#FILE);
    XMLElement  line;
    int         i;

    str xslt = ' <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> '+
               ' <xsl:output omit-xml-declaration="no" method="text" media-type="text/xml"       '+
               ' indent="no" encoding="'+#codePage+'" />                                         '+
               ' <xsl:template match="'+#LINE+'">                                                '+
               ' <xsl:apply-templates/>                                                          '+
               '        <xsl:if test="following-sibling::node()">                                '+
               '           <xsl:text>XXX</xsl:text>                                              '+
               '        </xsl:if>                                                                '+
               '     </xsl:template>                                                             '+
               '  </xsl:stylesheet>                                                              ';

    void outputXML(XMLDocument _xml)
    {
        COM         outputStream;
        XMLDocument xsl = XMLDocument::newXML(xslt);
        ;

        outputStream = new COM('ADODB.Stream');
        outputStream.type(1); // binary
        outputStream.open();

        _xml.com().transformNodeToObject(xsl.com(), outputStream);

        outputStream.saveToFile(#fileFullName);
        outputStream.close();
    }
    ;


    if (WinAPI::fileExists(#fileFullName))
        WinAPI::deleteFile(#fileFullName);

    doc.appendChild(file);

    for (i=1; i<=10; i++)
    {
        line = doc.createElement(#LINE);
        line.appendChild(doc.createTextNode(strFmt('line %1 ABCDE АБВГДЕЖЗИКабвгдежзик', i)));
        file.appendChild(line);
    }
    outputXML(doc);

    info('Готово');
}
XXX надо исправить на "
_;" без кавычек и подчёркивания

Также выражаю признательность и большую спасибу EVGL и belugin за полезные подсказки

Последний раз редактировалось zinius; 25.09.2008 в 17:46.
За это сообщение автора поблагодарили: d_alexe (1).
Старый 16.01.2009, 14:23   #4  
mix2ra is offline
mix2ra
Участник
 
1 / 10 (1) +
Регистрация: 16.01.2009
?
Hi, Sorry for using English but my Russian is worse than elementary
I would like to ask if it would be also possible to write to the file an Unicode sign 0x2028 (End of line)

XML would always replace this sign as well as new line sign '\n' with the 0x00
What need to be done in order to be able to write 0x2028 directly to the file.
Is it possible?

We are still using AX 3.0 (I know that in DAX 4 it is possible by using TextIO class)
Any clues?

Thanks!
Теги
unicode, xml, кодировка, ax3.0

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
dax-lessons: Generate XML Documentation Files for a project - DAX 2009 Blog bot DAX Blogs 0 08.08.2008 19:06
axStart: How to use XSLT in AIF and what’s wrong with empty xml Nodes. Blog bot DAX Blogs 0 27.04.2008 18:07
Inside Dynamics AX 4.0: The XML Structure Blog bot DAX Blogs 0 04.10.2007 11:20
Inside Dynamics AX 4.0: XML Document Integration Blog bot DAX Blogs 0 04.10.2007 11:20

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 16:02.