2014-10-24 1 views
2

Я пытаюсь написать XML-файл, закодированный в UTF-8, используя данные из базы данных Oracle 9 (также должен работать на Oracle 11), настроенный с помощью NLS_CHARACTERSET = US7ASCII, NLS_LANGUAGE = AMERICAN. Я использую функции XMLELEMENT и xmlattributes для создания clob, а затем создаю файл из этого clob.Как писать символы не-ascii в XML-файле UTF8 из US7ASCII База данных Oracle

Вот простой пример:

declare 
xmlval clob; 
begin 
    SELECT XMLELEMENT("Parent", 
     XMLELEMENT("Address", xmlattributes(unistr('N°27') as "Street", unistr('77800') as "PostCode", unistr('Paris') as "City")) 
     ).extract('/*').getclobVal() 
    INTO xmlval 
    FROM DUAL; 

    dbms_xslprocessor.clob2file(xmlval, 'DIRXMLTMP', 'file.xml', nls_charset_id('AL32UTF8')); 
end; 

Таблицы в базе данных может содержать несколько символов не-ASCII, как клиент использует, я думаю, кодовый набор символов для Windows 1252.

В настоящее время я должен использовать функцию unistr, иначе процедура вылетает, когда поле содержит символы не-ascii.

Теперь этот код может генерировать xml-файлы, но символы не-ascii заменяются символом '?' символ: «N ° 27» становится «N? 27».

Я пытался играть с функцией новообращенного для того, чтобы изменить строку «N ° 27» или переменную xmlval, например:

convert(xmlval, 'WE8MSWIN1252', 'US7ASCII') 
convert('N°27', 'US7ASCII', 'WE8MSWIN1252') 

Но я все еще получаю в "N 27? результирующий файл.

Можно ли отобразить эти конкретные символы в сгенерированном файле из базы данных us7ascii?

+0

Вместо UNISTR пытаются использовать ASCIISTR. Он преобразует национальный набор символов в представление «\ xxxx». И UNISTR преобразует «\ xxxx» обратно в национальный набор символов – Multisync

+0

Спасибо за подсказку, но по некоторым причинам я всегда получаю \ FFFD для всех разных персонажей, которые я пробовал: 'éè °' -> '\ FFFD \ FFFD \ FFFD ' – tetorea

+0

Я создал некоторую функцию для кодирования специальных символов в us7ascii аналогично тому, что должен делать asciistr, и соответствующей функции декодирования. – tetorea

ответ

2

Наконец, я получил некоторые обходной путь:

1- создать функцию для кодирования символов выше 127 как строка, представляющей соответствующего шестнадцатеричного код, окруженный конкретными разделителями: encodeSpecialChars («°») -> «# B0 # '

2- создать функцию для декодирования кодированных строк: decodeSpecialChars (' # В0 # ') -> '°'

3- создать XML CLOB путем фильтрации все поля

4- декодированием clob

5- новообращенный необработанных данных в CLOB в в UTF-8

6- сохранить данные исходного файла с помощью UTL_FILE и utl_raw пакетов

declare 
xmlval clob; 
begin 
    SELECT XMLELEMENT("Address", xmlattributes(encodeSpecialChars('N°27') as "Street", encodeSpecialChars('Frébault') as "City") 
     ).extract('/*').getclobVal() 
    INTO xmlval 
    FROM DUAL; 

    -- <Address Street="N#B0#27" City="Fr#E9#bault"/> 
    xmlval := decodeSpecialChars(xmlval); 
    -- <Address Street="N°27" City="Frébault"/>  -- encoded in Windows-1252 

    l_output := utl_file.fopen('DIRXMLTMP', 'fff.xml', 'w'); 
    utl_file.PUT_RAW(l_output, UTL_RAW.convert(UTL_RAW.CAST_TO_RAW(xmlval), 'FRENCH_FRANCE.AL32UTF8', 'FRENCH_FRANCE.WE8MSWIN1252')); 
    utl_file.fclose(l_output); 
end;