2011-05-15 44 views
9

我正在尋找一個簡短的示例/教程,介紹如何讀取,修改一個值並使用可可編寫一個xml文件。我發現的所有內容都是simple(只是讀或寫)或complex(是一個完整的xml編輯器)。閱讀,修改,在可可中編寫xml文件

這似乎是一個相當標準的使用場景,所以我希望有東西在那裏...

+0

[Cocoa/Obj-C簡單XML文件讀取器 - 需要幫助]的可能重複(http://stackoverflow.com/questions/5274513/cocoa-obj-c-simple-xml-file-reader-need-help) – 2011-05-15 20:08:10

+1

其中包括:[從XML中提取信息](http://stackoverflow.com/questions/3739854/)| [解析XML](http://stackoverflow.com/questions/1089737/parsing-xml-in-cocoa)| [解析XML的最佳實踐](http://stackoverflow.com/questions/2237757/)| [讀/寫XML](http://stackoverflow.com/questions/1072979/) – 2011-05-15 20:11:17

+1

謝謝,但我正在尋找一個示例,顯示如何閱讀,修改__and__寫一個XML樹。 '重複'不這樣做。假設我在xml文件中有(除其他外)一個簡單的計數器:。我如何解析,遞增並將其寫回文件? – hanno 2011-05-15 20:29:44

回答

6

我說錯了,當時我聲稱寫這樣的元素是無法完成的。 Apple有兩個XML解析器,一個用於NSDictionary/NSArray/NSString/NSNumber /等。對象和一個名爲NSXMLDocument的對象。

我已經刪除了先前的代碼,它與Mac OS X 10.3兼容;下面提到的代碼將允許您擁有包含您喜歡的任何標籤和屬性的xml文件。 在我的例子,該代碼將創建一個類似如下的XML文件:

<根> <計數器 /計數器> < /根>

注意:您甚至可以刪除「反'並將'root'重命名爲'counter',如果你想進一步減少它。

新代碼與Mac OS X 10.4兼容,並轉發;它的測試和工程外的開箱:

- (void)incrementCounter 
{ 
    NSXMLDocument *xmlDoc; 
    NSError   *error; 
    NSURL   *url; 
    NSXMLElement *root; 
    id    item; 
    NSData   *data; 
    NSArray   *children; 
    int    counter; 
    NSString  *pathname; 

    pathname = [@"~/myFile" stringByExpandingTildeInPath]; 
    url = [NSURL fileURLWithPath:pathname]; 

    xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:url options:NSXMLDocumentTidyXML error:&error]; 
    if(xmlDoc) 
    { 
     root = [xmlDoc rootElement]; 
    } 
    else 
    { 
     root = [NSXMLNode elementWithName:@"root"]; 
     xmlDoc = [[NSXMLDocument alloc] initWithRootElement:root]; 
    } 

    // fetch value: 
    children = [root nodesForXPath:@"counter" error:&error]; 
    item = [children count] ? [children objectAtIndex:0] : NULL; 

    // modify value: 
    counter = item ? [[item stringValue] intValue] : 0; 
    counter++; 
    if(NULL == item) 
    { 
     item = [NSXMLNode elementWithName:@"counter" stringValue:@"0"]; 
     [root insertChild:item atIndex:0]; 
    } 
    [item setStringValue:[[NSNumber numberWithInt:counter] stringValue]]; 

    // write: 
    data = [xmlDoc XMLData]; 
    [data writeToURL:url atomically:YES]; 
} 
+0

這個答案對我沒有任何意義。 – hanno 2013-02-16 15:15:40

+0

我現在改寫了我的答案。如果您需要支持10.4以下的Mac OS X,我將不得不重新編寫我的答案。這完全取決於您是否擁有NSXMLDocument類。 – 2013-02-17 18:00:20

+0

您是否使用上面的新代碼獲得它,或者您仍然遇到問題? ...嘗試調用[self incrementCounter];從一個全新的項目中-awakeFromNib;它應該在主目錄中生成'myFile',並且每次運行該程序時都會增加計數器。 – 2013-02-21 19:11:19

-4

如果你不熟悉xpath S,那麼我建議你在他們身上,xpath閱讀起來s是一種在xml樹中查找節點的方法。

+5

這是沒有答案,兒子..他的問一個具體問題......並建議他在xpaths上「閱讀」只是粗魯。我同意OP ...從我個人來說,我可以找到百萬種方法來讀取可可中的XML,但是對於我來說,無法找到一種簡單明瞭的方式來將NSArray或NSDictionary等轉換爲一個XML「對象」 - 爲了我的生活! – 2011-11-21 16:11:32

2

這裏是我的問題的解決方案 - 只有在我寫出來這是以前讀取並解析該文件的一部分...

使用PacMan的解決方案 - 我遇到了輸出xml 文件沒有很好格式化的問題根本沒有換行符)。

另一點是,我通常喜歡使用XPath導航XML文檔。

我的代碼是一個類的一部分,所以我有一個屬性爲每個節點(的NSString * cfaLayout和NSInteger的bitsPerPixel):

-(BOOL) savePropertiesFile{ 
BOOL isSuccess=FALSE; 
NSError* error; 
NSXMLElement* currentElement; 
NSArray* nodes; 

/* parse existing url file before saving it to new url */ 
if([_documentUrl checkResourceIsReachableAndReturnError:&error]==YES){ 
    self.document=[[NSXMLDocument alloc] 
           initWithContentsOfURL:_documentUrl 
           options:0 
           error:&error]; 

    /* check top node */ 
    nodes=[_document nodesForXPath:@"/ImageFormat-Properties" 
                error:&error]; 
    if([nodes count]==0){ 
     return FALSE; 
    } 

    /* cfa layout */ 
    nodes=[_document nodesForXPath:@"/ImageFormat-Properties/ImageFormatDetails/CFALayout[text()]" 
                error:&error]; 
    if([nodes count]>0){ 
     currentElement=[nodes objectAtIndex:0]; 
     [currentElement setStringValue:[_cfaLayout lowercaseString]]; 
    } 
    else{ 
     return FALSE; 
    } 

    /* bitsPerPixel */ 
    nodes=[_document nodesForXPath:@"/ImageFormat-Properties/ImageFormatDetails/BitsPerPixel[text()]" 
                error:&error]; 
    if([nodes count]>0){ 
     currentElement=[nodes objectAtIndex:0]; 
     [currentElement setStringValue:[NSString stringWithFormat: @"%ld", (long)_bitsPerPixel]]; 
    } 
    else{ 
     return FALSE; 
    } 
} 
[_document setDocumentContentKind:NSXMLDocumentXMLKind]; 
[_document setCharacterEncoding:@"UTF-8"]; 
[_document validateAndReturnError:&error]; 
if(error){ 
    return FALSE; 
} 

[self setDocumentUrl:_documentSaveAsUrl]; 
NSData* xmlData=[_document XMLDataWithOptions:NSXMLNodePrettyPrint]; 
isSuccess=[xmlData writeToURL:_documentSaveAsUrl atomically:YES]; 

return isSuccess; 

}

有人也許有用...