views:

73

answers:

1

I have a simple XML and I need to get the first 'id' from puid-list. I found lots of examples but none of them quite do that because of the namespace. How do get the id out as an NSString?

PS: I'm on a Mac.

<genpuid songs="1" xmlns:mip="http://musicip.com/ns/mip-1.0#"&gt;
  <track file="/htdocs/test.mp3" puid="0c9f2f0e-e72a-c461-9b9a-e18e8964ca20">
    <puid-list>
      <puid id="0c9f2f0e-e72a-c461-9b9a-e18e8964ca20"/>
    </puid-list>
  </track>
</genpuid>
+3  A: 

You should use NSXMLParser. Create an instance in your code and tell it to parse:

NSData * XMLData = [myXMLString dataUsingEncoding:NSUnicodeStringEncoding];
NSXMLParser * parser = [[NSXMLParser alloc] initWithData:XMLData];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:YES]; // if you need to
[parser parser];

then you need to implement the methods of NSXMLParserDelegate to get callbacks during parsing:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary *)attributeDict{

    /* handle namespaces here if you want */

    if([elementName isEqualToString:@"puid"]){
         NSString * ID = [attributeDict objectForKey:@"id"];
         // use ID string, or store it in an ivar so you can access it somewhere else
    }
}

Notes on handling namespaces:

If the namespaces are set, elementName is the qualified name, so could have prefix (e.g. mip:puid) If you're on the Mac, NSXMLNode has to convenience class methods, localNameForName: and prefixForName: to get the two parts of the string.

Also, You might want the NXXMLParser delegate methods parser:didStartMappingPrefix:toURI: and parser:didEndMappingPrefix:.

Note that names returned by NSXMLParser are exactly those from the string (regarding whether they're prefixed). So it's rare for the attribute to be named mip:id, but if you want to be robust, you need to check for this as well.

Mo