0

I'm looking a way to decode XML entities of some special characters like ( µ, Λ, μ, ν, π) for my iPad app. I went though the blogs and questions for hours to find a solution.

So I found this and I modified it by adding following code lines,

    else if ([scanner scanString:@"µ" intoString:NULL])
        [result appendString:@"µ"];
    else if ([scanner scanString:@"&Lambda" intoString:NULL])
        [result appendString:@"Λ"];
    else if ([scanner scanString:@"Π" intoString:NULL])
        [result appendString:@"Π"];

But I'm not feeling this as a good solution.

So, I'm looking someone's kind help for this.

XCode4 and iOS 4.3 are my development environment.

Community
  • 1
  • 1
chinthakad
  • 939
  • 2
  • 16
  • 31
  • You should explain why you feel like it isn't a good solution so that people can understand what you are looking for when they offer something else. – sosborn Apr 15 '12 at 09:10
  • The reason is, I have to put a else if condition per a character. http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references see there are lot of special characters. So, need a better solution to decode the xml entities without validate them one by one. – chinthakad Apr 15 '12 at 09:20

1 Answers1

1

Assuming that you've already decided that you're going to do this parsing by hand, as opposed to using NSXMLParser and the appropriate entity calls in the delegate, then you probably want to use a table-driven parser for this.

Since & in XML is always the introduction to an entity, it is safe to do something like this (assuming you're parsing XML and not HTML, which can have a significantly relaxed definition of what's allowed):

if ([scanner scanString: @"&" intoString: nil]) {
    NSString *entityNameString;
    if ([scanner scanUpToString: @";" intoString: entityNameString]) {
        NSString *entityValue =[entityDictionary objectForKey: entityNameString];
        if (entityValue)
             [result appendString: entityValue];
        else {
             // TODO: figure out if you want to blow an error, ignore the entity, or insert the original string
             [result appendString: [NSString stringWithFormat: @"&%@;", entityNameString]];
        }
    } else {
        // TODO: Determine if you want to blow an error, ignore, or insert the original string
        [result appendString: @"&"];
    }
}

entityDictionary would be a dictionary of key value pairs representing each entity and the string that it represents:

NSDictionary *entityDictionary = [NSDictionary dictionaryWithObjectsAndKeys: @"µ",@"micro", @"π", @"Pi",nil];

Or you could load from a plist using:

NSDictionary *entityDictionary = [NSDictionary dictionaryWithContentsOfURL: @"myEntityList.plist"];
gaige
  • 17,263
  • 6
  • 57
  • 68