2010-06-02 2 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> 

Как я могу получить доступ к атрибутам («английский», «китайский», «имя», «а», «б» и т.д.) и связанные с ними значения узлов MOVIE? В настоящее время у Cocoa есть возможность пересекать эти узлы, но я не понимаю, как я могу получить доступ к данным в MOVIE NSXMLNodes.

Есть ли способ сбросить все значения из каждого NSXMLNode в Hashtable и получить значения таким образом?

Использование 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. –

+0

Спасибо. Я не был уверен, как работают запросы XPath, но с вашим примером, приведенным в моем XML-файле, я вижу, как работают основные запросы. Прочитав XCode в Интернете, я был смущен примерами, потому что я не был уверен в том, что контекст будет использовать их. –

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

спасибо, что мечта! Я также нашел свое собственное решение этой проблемы, которое я также опубликовал. Но я соглашаюсь с тобой, потому что у тебя есть время и энергия, чтобы решить эту проблему. Спасибо, и я с нетерпением жду использования вашего кода в качестве ссылки. –

+0

@ Джеффри Керн: Хорошо, что я могу решить все по-твоему, в конце концов, у меня была ошибка в моем ответе;) – dreamlax

+0

Хех, я думаю, что ваше решение немного более элегантно, чем мое. :) –

Смежные вопросы