我最近改用 Delphi XE7 中包含的 OmniXML,以允许针对 iOS。 XML 数据来自云服务,包含具有 Base64 编码二进制数据的节点。
现在,在调用 XMLDocument.LoadFromStream 时,我收到此异常 “此平台的 Unicode 字符值无效”
,并且似乎是此 Base64 换行序列失败:
具有 Base64 数据的节点看起来类似于:
<data>TVRMUQAAAAIAAAAAFFo3FAAUAAEA8AADsAAAAEAAAABAAHAAwABgAAAAAAAAAAAQEBAAAAAAAA
AAMQAAABNUgAAP/f/AAMABAoAAAAEAAAAAEVNVExNAAAAAQAAAAAUWjcUABQAAQD/wAA
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 值) >)
如何解决这个问题?
最佳答案
这显然是 OmniXML 中的一个错误。看起来开发人员正在尝试实现 XML1.0 which states :
...XML processors MUST accept any character in the range specified for Char.
Character Range
[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
/* any Unicode character, excluding the surrogate blocks, FFFE, and 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 节)。
这看起来像是一个阻碍,应该作为质量控制报告提交。
关于delphi - iOS 上的 OmniXML : Invalid Unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30033288/