AXForum  
Zurück   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
CRM
Kennwort vergessen?
Registrieren Forum Rules Hilfe Benutzerliste Heutige Beiträge Suchen

 
 
Themen-Optionen Thema durchsuchen Ansicht
Alt 09.01.2006, 12:14   #1  
EVGL ist offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4.445 / 3001 (0) ++++++++++
Registriert seit: 09.07.2002
Ort: Parndorf, AT
Файлы XML, CSV, HTML в кодировке Unicode
Думаю, многим окажутся полезны мои изыскания в области представления текстовых данных в разных кодировках. Итак, задача: сгенерировать из Аксапта файл CSV в кодировке UTF-16.

Одно из решений - это создать промежуточный файл XML в "родной" кодировке Аксапта, а затем с помощью XSL-шаблона превратить его в CSV в соответствующей кодировке.

Это достигается следующим выражением xsl:
PHP-Code:
<xsl:output encoding="UTF-16" /> 
при условии, что в processing instructions XML-файла задана исходная "родная" для Аксапта кодировка: <?xml version="1.0" encoding="ISO-8859-2"?> (это для Польши, Венгрии и других восточноевропейских стран, использующих латинский алфавит).

А вот полный текст простого шаблона, который позволяет изменить кодировку XML-файла на желаемую:
PHP-Code:
<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-Code:
xmlString xmlDocument.transformNode(_xsltDocument
где функции transformNode передается класс XMLDocument с загруженным XSL-шаблоном, в ответ она возващает результат преобразования в виде строки.

Просто? Не тут-то было. Аксапта, как известно, продукт на чрезвычайно совеременной технологической платформе, и со строками Unicode работать не умеет.

По-видимому, уже в момент приема строки-результата из компонента Msxml2.DOMDocument Аксапта преобразовывает результат из Unicode обратно в "родную" 8-битную кодировку.

Рекомендованное решение - использовать не метод transformNode(), а метод transformNodeToObject(), который способен писать прямо в поток ADODB.Stream, т.е. писать результат на диск в обход Аксапта. Если разработать простой класс-обертку для ADODB.Stream, то код в Аксапта может выглядеть так:

PHP-Code:
outputStream = new ADODBStream();
outputStream.type(1); // binary
outputStream.open();

_outputDocument.com().transformNodeToObject(_xsltDocument.com(),
                                            
outputStream.com());

outputStream.saveToFile(outputFileNameFull);
outputStream.close(); 
Все! Осталось заметить, что по вышеуказанным причинам модуль Commerce Gateway сохранять XML-файлы в кодировках, отличных от "родной", не умеет. По крайней мере, без дополнительных доработок.

Geändert von EVGL (09.01.2006 um 17:21 Uhr)
This post has been rated by: mazzy (18), belugin (14), kashperuk (1), zinius (1), alex55 (1), mix2ra (1).
Alt 09.01.2006, 12:36   #2  
mazzy ist offline
mazzy
Участник
Benutzerbild von mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29.472 / 4494 (208) ++++++++++
Registriert seit: 29.11.2001
Ort: Москва
Blog-Einträge: 10
Спасибо. Добавил респект.
__________________
полезное на axForum, github, vk, coub.
Alt 25.09.2008, 17:26   #3  
zinius ist offline
zinius
Участник
 
24 / 11 (1) +
Registriert seit: 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 за полезные подсказки

Geändert von zinius (25.09.2008 um 17:46 Uhr)
This post has been rated by: d_alexe (1).
Alt 16.01.2009, 14:23   #4  
mix2ra ist offline
mix2ra
Участник
 
1 / 10 (1) +
Registriert seit: 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!
Stichworte
unicode, xml, кодировка, ax3.0

 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
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

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Gehe zu

Рейтинг@Mail.ru
Alle Zeitangaben in WEZ +3. Es ist jetzt 21:55 Uhr.
Powered by vBulletin® Version 3.8.5 (Deutsch)
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.