2012-01-05 18 views
0

私はこのバグを修正する必要があるので、私自身の質問に答える可能性が高いですが、それは文書化のためです。注:SAXパーサーは、他のすべての質問/回答と同様に使用していません。NSStringの代わりにXML CDataセクションからNSDataを読み取る

NSMutableData* data = ... 

NSXMLNode* nodeCDATA= [[NSXMLNode alloc] initWithKind:NSXMLTextKind options:NSXMLNodeIsCDATA]; 
[nodeCDATA setObjectValue:data]; 

NSAssert([nodeCDATA.objectValue isKindOfClass:[NSData class]], @"NSXMLNode setObjectValue didn't use a NSData"); 

同じ機能の中で、最後のNSAssertは発火しないことに注意してください。 しかし、xmlをサーバーに送信した後、戻り値の型としてNSStringを取得します。

NSXMLNode* nodeCDATA= [dx childAtIndex:0]; 

id obj= nodeCDATA.objectValue; 
if (![obj isKindOfClass:[NSData class]]) 
    NSLog(@"Why am I getting a %@ returned from a CDATA section!?",[obj class]); 

出力がある...

2012-01-05 13:58:29.336 auth[18773:1f03] Why am I getting a __NSCFString returned from a CDATA section!? 

すべてのヘルプは高く評価され、感謝します。

=====更新:

質問はまだ開いています。 NSMutableDataをNSStringにエンコードしてsetStringValueを使用するための外部ベース64暗号化ソリューションを見つけることがベストなソリューションでした。それから、base64の解読を使ってstringValueから返された文字列を解読し、問題を回避します。

具体的には、http://www.cocoadev.com/index.pl?BaseSixtyFourから - (NSString *)base64Encodingを使用してjimmy rigにしましたが、NSDataバイトの生の書き込みをBSON形式に実装して、カットするかどうかを確認します。私は、base64ではデータサイズが約33%増加していると読んでいます。可能ならばそれを避けたいと思います。

上記の解決策は、依然として大歓迎です。

=== MORE UPDATE ===

私がに見てきたいくつかのオプションは、DTDとXSLです。 MSXML.dllには長い間前と同じ問題がありました。私のデータがNSDataとして返されたいbase64文字データであることをApple APIに確信させるためにDTDを割り当てるか、XSL変換を行うことができればうまくいくでしょう。誰にもこのコードがありますか?私はDTDでxs:base64Binaryタグの非規範的な使用を見出しましたが、Apple IDがそれを受け入れるなら試していません。ちょうどそれが働くかどうか見るのに多すぎる仕事。

答えて

1

CDATAセクションはバイナリデータを渡すことを目的としたものではありません。具体的には、マークアップではなく文字データと解釈される必要があるコンテンツのセクションをマークすることを特に意図しています。 CDATAノード内のデータとテキストノード内のデータの間に意味的な違いはありません。バイナリデータをエンコードする必要がある場合は、UTF-8と互換性のあるものに変換する必要があります。 Base64が典型的な選択肢です。しばしば誤って、その目的は、通常の文字データとして処理されることから、データを「保護」することであると信じて、CDATAセクションの目的を誤解XML文書の

新しい著者:

はここwikipedia pageから関連の通路です処理中。 XML文書を扱ういくつかのAPIは、CDATAセクションへの独立したアクセスのオプションを提供しますが、そのようなオプションはXML処理システムの通常の要件を超えて存在しますが、依然としてデータの暗黙の意味を変更しません。文字データは、CDATAセクションまたは通常のマークアップを使用して表現されているかどうかにかかわらず、文字データです。

このすべての最終結果はNSXMLNode APIは、入力としてNSDataを受け入れるかもしれないが、彼らは外部の文書を解析した後NSDataを提供する義務を負いませんしているということです。実際には、CDATAセクションの内容は文字データなので、NSXMLNodeNSString(あなたの言ったように)を返す方が正しいです。

+0

ケビン、あなたはまったく正しいです。しかし、私が探しているのは、どのような場合でもNSDataを取得する方法です。私はおそらくxs:base64Binaryタグを使ってDTDとXSLを見てきましたが、これを行うための明確な方法はありません。 – PLG

+0

私も述べましたが、同じ関数(NSAssert文)のノードからデータを取り出すと、データはNSDataとして返されます。だから、私は伝送後も同じことをしたい。 – PLG

+0

@PLG: 'objectValue'を' NSData'に設定してすぐに再びそれを取り出すと、それはあなたが与えたのとまったく同じ 'NSData'を与えます。しかし、XML文書を解析してノードに 'objectValue'を尋ねると、' NSString'が得られます。代わりに 'stringValue'と' setStringValue: 'を使用し、' NSData' <-> NSString(例えばbase64など)の間で独自の変換を使用することをお勧めします –

関連する問題