2015-05-04 2 views
2

Недавно я переключился на использование OmniXML, входящего в состав Delphi XE7, чтобы настроить таргетинг на iOS. Данные XML поступают из облачной службы и включают узлы с двоичными данными с кодировкой base64.OmniXML на iOS: Недействительный Юникод

Теперь я получаю эту exeception "Invalid Unicode Character value for this platform" при вызове XMLDocument.LoadFromStream, и это, кажется, это base64 последовательность LINEBREAK, которая не: 

Узлы с данными base64 выглядит примерно так:

<data>TVRMUQAAAAIAAAAAFFo3FAAUAAEA8AADsAAAAEAAAABAAHAAwABgAAAAAAAAAAAQEBAAAAAAAA&#xD; 
AAMQAAABNUgAAP/f/AAMABAoAAAAEAAAAAEVNVExNAAAAAQAAAAAUWjcUABQAAQD/wAA&#xD; 
AAA=</data> 

Я проследил его до этих строк в XML.Internal.OmniXML:

psCharHexRef: 
    if CharIs_WhiteSpace(ReadChar) then 
     raise EXMLException.CreateParseError(INVALID_CHARACTER_ERR, MSG_E_UNEXPECTED_WHITESPACE, []) 
    else 
    begin 
     case ReadChar of 
     '0'..'9': CharRef := LongWord(CharRef shl 4) + LongWord(Ord(ReadChar) - 48); 
     'A'..'F': CharRef := LongWord(CharRef shl 4) + LongWord(Ord(ReadChar) - 65 + 10); 
     'a'..'f': CharRef := LongWord(CharRef shl 4) + LongWord(Ord(ReadChar) - 97 + 10); 
     ';': 
      if CharIs_Char(Char(CharRef)) then 
      begin 
      Result := Char(CharRef); 
      Exit; 
      end 
      else 
      raise EXMLException.CreateParseError(INVALID_CHARACTER_ERR, MSG_E_INVALID_UNICODE, []); 

это исключение в последней строке, которая поднята, потому что CharIs_Char(#13) является ложным (где # 13 - значение CharRef, считанное с &#xD;)

Как это решить?

ответ

3

Это явно ошибка в OmniXML. Похоже, разработчики пытались реализовать XML1.0 which states:

... Процессоры XML ДОЛЖНЫ принимать любые символы в диапазоне, указанном для Char.

Диапазон символов

[2] Char :: = # x9 | #xA | #xD | [# x20- # xD7FF] | [# xE000- # xFFFD] | [# x10000- # x10FFFF]

/* любой символ Юникода, за исключением суррогатных блоков, FFFE и FFFF. */

Реализация CharIs_Char, однако выглядит следующим образом:

function CharIs_Char(const ch: Char): Boolean; 
begin 
    // [2] Char - any Unicode character, excluding the surrogate blocks, FFFE, and FFFF 
    Result := not Ch.IsControl; 
end; 

Это исключая все управляющие символы, которые включают в себя #x9 (TAB), #xA (LF) и #xD (CR). Фактически, поскольку XML-полосы (или, возможно, заменяющие LF) символы возврата каретки во время разбора, единственный способ включить фактический возврат каретки - использовать ссылку на символ в литеральном значении сущности (раздел 2.3 спецификации).

Это похоже на демонстрационный стенд и должно быть представлено в виде отчета о контроле качества.

+0

Установка 'DefaultDOMVendor: = sAdom4XmlVendor;' решена проблема. Кто должен был знать, что строки являются такой необычной особенностью XML-документа, что никто не обнаружил эту ошибку в OmniXML ... – Hans

Смежные вопросы