NSXMLParserとBOMバイト
-
20-09-2019 - |
質問
私はいくつかのサーバーからPHPのクエリの結果として、私のxmlファイルを取得しています。私はコンソールに結果のデータを印刷するとき、私は、よく構造化されたXMLファイルを取得しています。空のドキュメント - 私はNSXMLParserを使用してそれを解析しようとすると、それはコード4でNSXMLParserErrorDomainを返します。 私はそれが正しいXMLヘッダの「>」マークを閉じた後にBOM(バイトオーダーマーク)の配列を有する解析できなかったことをXMLSました。質問は、BOMシーケンスを取り除く方法です。これらのBOMはそのようバイトで私は、文字列を作成しようとしました。
const UInt8 bom[3] = {0xEF, 0xBB, 0xBF};
NSString *bomString = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bom length:3] encoding:NSUTF8StringEncoding];
NSString *noBOMString = [theResult stringByReplacingOccurrencesOfString:bomString withString:@" "];
が、それは何らかの理由で動作しません。ルート要素の後に、この配列を有しXMLSがあります。この場合、NSXMLParserが正常にXMLを解析します。 Safariはそれらの文字を無視します。だから、Xcodeのデバッガ。助けてください!
おかげで、
ナバ
解決
私はそれらのBOMを持つ文字列を作成しようとしましたがそのようにバイトます:
const UInt8 bom[3] = {0xEF, 0xBB, 0xBF}; NSString *bomString = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bom length:3] encoding:NSUTF8StringEncoding]; NSString *noBOMString = [theResult stringByReplacingOccurrencesOfString:bomString withString:@" "];
が、それは何らかの理由で動作しません。
noBOMString
をインスタンス化するときに正しいエンコーディングを与えたことを確認してください。文書データがUTF-8だった場合、あなたはUTF-8などの文字列をインスタンス化してください。データはUTF-16であれば同様に、あなたはUTF-16などの文字列をインスタンス化することを確認します。
あなたは間違ったエンコーディングを渡し、いずれかの文字列がすべてではインスタンス化しません(私はそれがあなたの問題ではありませんと仮定しています)、または一部の文字が間違っていることになる場合。 BOMは、これらの1のようになります。入力がUTF-8であり、あなたがMacRomanのかISOLatin1としてそれを解釈している場合、それは3つの別々の文字として文字列で表示されます。これらの3つの別々の文字はBOMである単一の文字に等しいとしません。
他のヒント
私は、これが問題であることは確かではありませんよ。私は、ファイルがUTF-8としてエンコードされた非常によく似た実務経験を持っていたが、XMLヘッダは、それがUTF-16であることを主張しました。
私はあなたが持っていた同じエラーでそれを解析することができませんでした不一致の結果として。ただし、UTF-8にUTF-16からのXMLヘッダを変更することは私のために問題を修正します。
あなたは同様の問題を経験することができます。
まあ、これはBOMバイトを取り除くために最善のアプローチではないかもしれませんが、それは動作します。部品表を飲み込むことNSXMLParserをしようと私のような時間を過ごした人のために: あなたはNSURLConnectionを通して、あなたのデータを取得し、NSMutableData * WEBDATAに保管していること、を考える。
const char bom[3] = {0xEF, 0xBB, 0xBF};
char *data = [webData mutableBytes];
char *cp = data, *pp;
long lessBom = 0;
do {
cp = strstr((const char *)cp, (const char *)bom);
if (cp) {
pp = cp;
cp += 3;
memcpy(pp, cp, strlen(cp));
lessBom += 3;
}
} while (cp != NULL);
NSMutableData *newData = [[NSMutableData alloc] initWithBytes:data length:webData.length - lessBom];
次に、あなたがあるnewDataであなたのパーサを作成し、それだけで動作します!私は、このコードに任意のコメント/改善を得るために喜んでいるよ。