2

次の形式の行としてアプリケーションに到着するテキスト ファイルがあります。

<row amount="192.00" store="10" transaction_date="2009-10-22T12:08:49.640"
 comp_name="何とか"
 comp_ref="C65551253E7A4589A54D7CCD468D8AFA"
 name="アクリントン "/>

そして、この「行」を、指定された TStringList 内の一連の名前/値のペアに変換したいと思います (ファイル内にこれらの<row>が数十個存在する可能性があるため、最終的には、それぞれを分割してファイルを反復処理する必要があります)。名前/値のペアに順番に行)。

私が抱えている問題は、データが明らかに区切られていないことです(技術的には、スペースで区切られていると思います)。一部の値に先頭または末尾のスペースが含まれていない場合は、いくつかの合理的な仮定を立てて、スペースに基づいて行を分割するコードを作成できたはずです。しかし、値自体にスペースが含まれる場合と含まれない場合があるため、これを行う明確な方法がわかりません。Delphi の TStringList.CommaText は役に立たず、Delimiter をいじってみましたが、毎回値内のスペースに引っかかってしまいます。

上記のサンプルをこれに似たものに変えるための巧妙な Delphi テクニックを持っている人はいますか? ;

amount="192.00"
ストア="10"
transaction_date="2009-10-22T12:08:49.640"
comp_name="何とか"
comp_ref="C65551253E7A4589A54D7CCD468D8AFA"
name="アクリントン"

残念ながら、この種の場合によくあることですが、最初からデータの形式を制御することはできません。たとえば、元に戻ってソースでカンマ区切りにすることはできません。おそらく、コードをコンマ区切りに変換するコードを書くことができると思いますが、私が持っているものを操作するための良い方法を見つけたいと思います。

違いがある場合、これは Delphi 2007 になります。

4

2 に答える 2

12

「明らかに区切られている」わけではないとおっしゃっていますが、私にとっては、明らかにXMLであるため、明らかに区切られています。したがって、XMLパーサーを使用してください。Delphiのから始めることができTXmlDocumentます。各「行」文字列を個別にパーサーに渡すこともできますが、私の疑いでは、これらの行はすべて他の山かっこタグで囲まれています。そのファイル全体をパーサーにフィードすると、行を表すオブジェクトのリストを取得するのに役立ち、名前でそれらの属性の値を要求できます。

XML解析のニュアンスに関係なくXMLを解析しようとすると、遅かれ早かれやけどを負うことになります。

于 2010-05-03T15:34:39.853 に答える
3
procedure RowToStrings(const row: string; list: TStrings);
var
  i       : integer;
  iDelim  : integer;
  inQuotes: boolean;
begin
  iDelim := 0;
  inQuotes := false;
  for i := 1 to Length(row) do begin
    if (row[i] = ' ') and (not inQuotes) then begin
      list.Add(Copy(row, iDelim+1, i-iDelim-1));
      iDelim := i;
    end
    else if row[i] = '"' then
      inQuotes := not inQuotes;
  end;
  list.Add(Copy(row, iDelim+1, Length(row)-iDelim));
end;

procedure TForm37.Test;
var
  row: string;
begin
  row := 'amount="192.00" store="10" transaction_date="2009-10-22T12:08:49.640" ' +
         'comp_name="blah                                            " '          +
         'comp_ref="C65551253E7A4589A54D7CCD468D8AFA" '                           +
         'name="Accrington                                                  "';
  RowToStrings(row, ListBox1.Items);
end;
于 2010-05-03T14:36:52.753 に答える