2010-06-02 56 views
11

考慮下面的XML文件:解析NSXMLNode屬性可可

<?xml version="1.0" encoding="UTF-8"?> 
<application name="foo"> 
<movie name="tc" english="tce.swf" chinese="tcc.swf" a="1" b="10" c="20" /> 
<movie name="tl" english="tle.swf" chinese="tlc.swf" d="30" e="40" f="50" /> 
</application> 

如何訪問屬性( 「英語」, 「中國人」, 「姓名」, 「A」, 「B」,等等。 )及其MOVIE節點的相關值?我目前在Cocoa有能力遍歷這些節點,但是我對如何訪問MOVIE NSXMLNodes中的數據感到迷茫。

有沒有一種方法可以將每個NSXMLNode的所有值轉儲到散列表中並以這種方式檢索值?

正在使用NSXMLDocument和NSXMLNodes。

回答

12

是的!莫名其妙地回答了我自己的問題。

在遍歷XML文檔時,不是將每個子節點指定爲NSXMLNode,而是將其指定爲NSXMLElement。然後,您可以使用attributeForName函數返回一個NSXMLNode,您可以使用stringValue來獲取該屬性的值。

由於我不擅於解釋事情,這裏是我評論的代碼。這可能會更有意義。

//make sure that the XML doc is valid 
if (xmlDoc != nil) { 
      //get all of the children from the root node into an array 
      NSArray *children = [[xmlDoc rootElement] children]; 
      int i, count = [children count]; 

      //loop through each child 
      for (i=0; i < count; i++) { 
       NSXMLElement *child = [children objectAtIndex:i]; 

        //check to see if the child node is of 'movie' type 
        if ([child.name isEqual:@"movie"]) { 
        { 
         NSXMLNode *movieName = [child attributeForName:@"name"]; 
         NSString *movieValue = [movieName stringValue]; 

         //verify that the value of 'name' attribute of the node equals the value we're looking for, which is 'tc' 
         if ([movieValue isEqual:@"tc"]) { 
         //do stuff here if name's value for the movie tag is tc. 
         } 
        } 
      } 
    } 
+0

您也可以使用 深入查看您想要的節點[xmldoc nodesForXPath:@「/ application/movie [@ name ='tc']」error:err] 您可以使用返回的節點作爲評估的新上下文節點進一步的XPath表達式。 – 2010-06-03 04:50:46

+0

謝謝。我不確定XPath查詢是如何工作的,但是通過我的XML文件給出的示例,我可以看到基本查詢是如何工作的。在互聯網上閱讀XCode,我很困惑這些例子,因爲我不確定使用它們的上下文。 – 2010-06-03 19:25:46

9

有兩種選擇。如果繼續使用NSXMLDocment和您對電影元素的NSXMLNode *,你可以這樣做:

if ([movieNode kind] == NSXMLElementKind) 
{ 
    NSXMLElement *movieElement = (NSXMLElement *) movieNode; 
    NSArray *attributes = [movieElement attributes]; 

    for (NSXMLNode *attribute in attributes) 
    { 
     NSLog (@"%@ = %@", [attribute name], [attribute stringValue]); 
    } 
} 

否則,您可以切換到使用NSXMLParser代替。這是一個事件驅動的解析器,它在解析元素時通知委託(等等)。你之後的方法是parser:didStartElement:namespaceURI:qualifiedName:attributes:

- (void) loadXMLFile 
{ 
    NSXMLParser *parser = [NSXMLParser parserWithContentsOfURL:@"file:///Users/jkem/test.xml"]; 
    [parser setDelegate:self]; 
    [parser parse]; 
} 


// ... later ... 

-  (void)   parser:(NSXMLParser *)parser 
      didStartElement:(NSString *)elementName 
       namespaceURI:(NSString *)namespaceURI 
       qualifiedName:(NSString *)qualifiedName 
        attributes:(NSDictionary *)attributeDict 
{ 
    if ([elementName isEqualToString:@"movie"]) 
    { 
     NSLog (@"%@", [attributeDict objectForKey:@"a"]); 
     NSLog (@"%d", [[attributeDict objectForKey:@"b"] intValue]); 
    } 
} 
+0

謝謝dreamlax!我也發現了我自己的解決方案,我也發佈了這個問題。但我接受你的觀點,因爲你花費時間和精力去解決它。謝謝,我也期待着使用你的代碼作爲參考。 – 2010-06-03 00:35:10

+0

@Jeffrey Kern:這是很好的解決你自己的事情,畢竟,我的答案中有一個錯誤;) – dreamlax 2010-06-03 00:44:23

+0

嘿,我認爲你的解決方案比我的更優雅一點。 :) – 2010-06-03 00:49:04