2

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

现在我"Invalid Unicode Character value for this platform"在调用 XMLDocument.LoadFromStream 时遇到了这个异常,这似乎是这个 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 是从中读取的 CharRef 的值&#xD;

我该如何解决这个问题?

4

1 回答 1

3

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

...XML 处理器必须接受为 Char 指定的范围内的任何字符。

字符范围

[2] 字符 ::= #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 节)。

这似乎是一个亮点,应该作为 QC 报告提交。

于 2015-05-04T16:13:40.270 回答