2

私は最近、iOS をターゲットにするために、Delphi XE7 に含まれている OmniXML を使用するように切り替えました。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, []);

が falseであるため発生するのは最後の行の例外ですCharIs_Char(#13)(ここで #13 は から読み取られた CharRef の値です&#xD;) 。

これを解決するにはどうすればよいですか?

4

1 に答える 1

3

これは明らかに OmniXML のバグです。開発者は次のように述べている XML1.0 を実装しようとしていたようです。

...XML プロセッサは、Char に指定された範囲内の任意の文字を受け入れなければなりません。

文字範囲

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

/* サロゲート ブロック、FFFE、および FFFF を除く、任意の Unicode 文字。*/

ただし、の実装は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 に答える