2010-12-05 33 views
2

ネストされたNSScannerは、繰り返し要素の文字列を解析するための最も効率的な方法ですか?スキャンは1回のパスで実行できますか?ネスト化されたNSScannerの効率

<jobStatus name="compressor.motn" submissionTime="12/4/10 3:56:16 PM" 
sentBy="localuser" jobType="Compressor" priority="HighPriority" 
timeElapsed="32 second(s)" timeRemaining="0" timeElapsedSeconds="32" 
timeRemainingSeconds="0" percentComplete="100" resumePercentComplete="100" 
status="Successful" jobid="CD4046D8-CDC1-4F2D-B9A8-460DF6AF184E" 
batchid="0C9041F5-A499-4D00-A26A-D7508EAF3F85" /jobStatus> 

が、私はアップル社のコンプレッサーへのコマンドラインコール(NSTAsk)から返された文字列を持っている(ない改行が存在しない、破損は純粋にスクロールせずに読みやすいというこの質問を容易にするためにあります)また

<jobstatus .... /jobstatus><jobstatus .... /jobstatus> 
<jobstatus .... /jobstatus> 

は、自分のコードにない重要で(この例ではbatchstatus)も含まれる他のタグが存在し得る:

同じストリング内のこれらの反復は、従って、戻り列にこれらのNを通じてゼロが存在し得ます:

<jobstatus .... /jobstatus><batchstatus .... /batchstatus> 
<jobstatus .... /jobstatus> 

これは返されるXMLドキュメントではなく、一連のステータスブロックだけがタグのようなXMLにラップされています。どのブロックも入れ子になっていません。それらはすべて本質的に逐次的である。私は返されるデータを制御できません。

私の目標(現在作業中のコード)は、文字列を "job"に分解して、jobstatusブロック内の詳細の辞書を含んでいます。他のブロック(batchstatusなど)およびその他の文字列は無視されます。私はjobstatusブロックの内容にのみ関心があります。

NSScanner * jobScanner = [NSScanner scannerWithString:dataAsString]; 
NSScanner * detailScanner = nil; 

NSMutableDictionary * jobDictionary = [NSMutableDictionary dictionary]; 
NSMutableArray * jobsArray = [NSMutableArray array]; 

NSString * key = @""; 
NSString * value = @""; 

NSString * jobStatus = @""; 

NSCharacterSet * whitespace = [NSCharacterSet whitespaceCharacterSet]; 

while ([jobScanner isAtEnd] == NO) { 

    if ([jobScanner scanUpToString:@"<jobstatus " intoString:NULL] && 
     [jobScanner scanUpToCharactersFromSet:whitespace intoString:NULL] && 
     [jobScanner scanUpToString:@" /jobstatus>" intoString:&jobStatus]) { 

     detailScanner = [NSScanner scannerWithString:jobStatus]; 

     [jobDictionary removeAllObjects]; 

     while ([detailScanner isAtEnd] == NO) { 

      if ([detailScanner scanUpToString:@"=" intoString:&key] && 
       [detailScanner scanString:@"=\"" intoString:NULL] && 
       [detailScanner scanUpToString:@"\"" intoString:&value] && 
       [detailScanner scanString:@"\"" intoString:NULL]) { 

       [jobDictionary setObject:value forKey:key]; 

       //NSLog(@"Key:(%@) Value:(%@)", key, value); 
      } 
     } 

     [jobsArray addObject: 
     [NSDictionary dictionaryWithDictionary:jobDictionary]]; 
    } 

} 

NSLog(@"Jobs Dictionary:%@", jobsArray); 

上記のコードは次のログ出力を生成します

Jobs Dictionary:(
    { 
    batchid = "0C9041F5-A499-4D00-A26A-D7508EAF3F85"; 
    jobType = Compressor; 
    jobid = "CD4046D8-CDC1-4F2D-B9A8-460DF6AF184E"; 
    name = "compressor.motn"; 
    percentComplete = 100; 
    priority = HighPriority; 
    resumePercentComplete = 100; 
    sentBy = localuser; 
    status = Successful; 
    submissionTime = "12/4/10 3:56:16 PM"; 
    timeElapsed = "32 second(s)"; 
    timeElapsedSeconds = 32; 
    timeRemaining = 0; 
    timeRemainingSeconds = 0; 
} 

ここで懸念があります。私のコードでは、文字列をスキャンしてから、データブロックを取得し、その部分をスキャンして配列にデータを入れる辞書を作成します。これは事実上、文字列が2回歩くことを意味します。これは15〜30秒ごとに発生し、何百ものジョブが含まれている可能性があるため、これは潜在的なCPUとメモリの塊であり、これを実行するアプリケーションはCompressorアプリと同じマシン上にある可能性がありますすでにメモリとCPUの豚) - 私はする必要がない場合、私は負担を追加したくないです。

データを取得するためにNSScannerを使用する必要がありますか?

ご迷惑をおかけして申し訳ありません。

答えて

1

jobScannerがスキャンしたjobStatusでdetailScannerを構築しているという点で、ネスティングは問題ありません。それは問題じゃない。あなたは2つの他があります。 1つは、空白文字をあまりにも多く汗ばませているが、それよりも悪い場合、最外ループは、条件付きの初期条件が形成されるため、決して終了しないということです。

変更

if ([jobScanner scanUpToString:@"<jobstatus " intoString:NULL] && 
[jobScanner scanUpToCharactersFromSet:whitespace intoString:NULL] && 
[jobScanner scanUpToString:@" /jobstatus>" intoString:&jobStatus]) 

もちろん

if ([jobScanner scanString:@"<jobstatus" intoString:NULL] && 
[jobScanner scanUpToString:@"/jobstatus>" intoString:&jobStatus] && 
[jobScanner scanString:@"/jobstatus>" intoString:NULL]) 

に、あなたはあなたの空白文字セットをキャッシュするあなたの行を削除することができます。空白文字をスキャンする必要はなく、スキャンまたはスキャンする文字列に空白文字を含める必要はありません。デフォルトでは、スキャナは空白文字をスキップします。あなたの最初のNSLogステートメントのコメントを外します。アウトプットにはどこにも迷子のスペースはありません。

ただし、指定した文字列までスキャンした後、その文字列自体をスキャンする必要があります。または、次の繰り返しのために最後に移動しないでください。

それ以外は、あなたのアプローチは健全だと思います。

+0

trudyscousin - ありがとう!これらの変更はスムーズに行われています。私はキャラクターセットについて心配していたボットでしたが、これはドキュメントによると高価な操作ですが、もちろん空白のビットがスキップされてしまったので、とにかくそれが疑わしいものになりました!再度、感謝します! – Hooligancat

関連する問題