iOS上的OmniXML:无效的Unicode

时间:2015-05-04 14:55:58

标签: delphi firemonkey delphi-xe7 omnixml

我最近转而使用Delphi XE7附带的OmniXML,以允许定位iOS。 XML数据来自云服务,包括具有base64编码二进制数据的节点。

现在,在调用XMLDocument.LoadFromStream时,我得到了这个例外"Invalid Unicode Character value for this platform",而这似乎是这个base64换行序列失败了:

具有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)为false(其中#13是从&#xD;读取的CharRef的值)

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

这显然是OmniXML中的一个错误。看起来开发人员正在尝试实现XML1.0 which states

  

... XML处理器必须接受为Char。

指定的范围内的任何字符      

角色范围

     

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

     

/ *任何Unicode字符,不包括代理块,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节)。

这似乎是一个显示器,应该作为质量控制报告提交。