2012-01-05 71 views
0

我很可能最終回答了我自己的問題,因爲在我繼續之前需要修復此錯誤,但這是爲了文檔目的。注:我沒有像使用其他問題/答案一樣使用SAX解析器。從XML CData部分讀取NSData而不是NSString

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!? 

任何幫助表示讚賞,感謝。

=====更新=====

問題仍然存在。我找到的最佳解決方案是找到一個外部base64加密解決方案,將NSMutableData編碼爲NSString,然後使用setStringValue。然後我使用base64的解密來解密stringValue返回的字符串,避免了這個問題。確切地說,我用 - (NSString *)base64Encoding從http://www.cocoadev.com/index.pl?BaseSixtyFour到現在的jimmy rig,但我很可能會實現NSData字節原始寫入BSON格式,看看是否會削減它。我讀到base64數據大小增加了33%,我認爲如果可能的話,我想避免這種情況。

以上解決方案仍然非常受歡迎。

===更多更新===

我已經看着有些選項DTD和XSL。很久以前,MSXML.dll也出現了同樣的問題。如果我可以分配DTD或執行XSL轉換來說服Apple API說我的數據是我想要作爲NSData返回的base64字符數據,那就好了。有沒有人有這個代碼?我確實在DTD中發現了非標準化的xs:base64Binary標記,但是如果Apple ID接受它,我還沒有嘗試過。太多的工作只是爲了看看它是否有效。

回答

1

CDATA部分不能讓您傳遞二進制數據。它們專門用於標記只能解釋爲字符數據而不是標記的內容部分。 CDATA節點內的數據與文本節點內的數據之間沒有語義差異。如果您需要編碼二進制數據,則需要將其轉換爲與UTF-8兼容的內容。 Base64是典型的選擇。

下面是來自wikipedia page相關通道:

XML文檔的新作者往往誤解CDATA節的目的,誤以爲其目的是爲了「保護」數據從被視爲普通字符數據在處理期間。一些用於處理XML文檔的API確實提供了獨立訪問CDATA節的選項,但這些選項超出了XML處理系統的正常需求,並且仍然不會改變數據的隱含含義。字符數據是字符數據,無論它是通過CDATA節還是普通標記表示。

所有這一切的最終結果是,雖然NSXMLNode的API可以接受NSData作爲輸入,他們沒有義務解析外部文檔後,爲您提供一個NSData。實際上,由於CDATA部分的內容是字符數據,因此NSXMLNode返回NSString(正如您所說的那樣),則更爲正確。

+0

凱文,你完全正確。但是,我正在尋找的是在任何情況下獲取NSData的方法。我使用xs:base64Binary標籤查看了DTD和XSL,但是我沒有看到完成這個過程的明確方法。 – PLG 2012-01-08 10:50:44

+0

正如我所說的,當我從同一個函數(NSAssert語句)中的節點中提取數據時,數據將作爲NSData返回。所以,我想在傳輸後達到同樣的效果。 – PLG 2012-01-08 10:52:56

+0

@PLG:當您將'objectValue'設置爲'NSData',然後立即再次將其拉出時,它會給您與您給出的完全相同的'NSData'。但是如果你解析一個XML文檔,然後詢問節點的'objectValue',你會得到一個'NSString'。我建議使用'stringValue'和'setStringValue:'來代替,並且在'NSData'之間使用自己的轉換'NSString'(例如base64或其他) – 2012-01-08 12:35:51