Im converting an XML String into an array using XML reader. The parser is adding a child element to the key “value” and my obj-c skills aren’t good enough to figure out how to prevent it – Im a PHP guy and helping out a friend. I also need to get 2 child elements down so offices and office done appear.
What im inputing
<?xml version="1.0" encoding="utf-8"?>
<offices>
<office>
<phone>02-7532490</phone>
<address>312 Sen. Gil Puyat Avenue, 18th Flr. Trident Tower</address>
<suburb>Makati</suburb>
<postcode>1200</postcode>
<email>careers@drakepersonnel.com.ph</email>
<name>Drake Makati</name>
<latitude>14.56213</latitude>
<longitude>121.02437</longitude>
</office>
</offices>
What i get back from the parser
{
offices = {
office = {
Address = {
value = "312 Sen. Gil Puyat Avenue, 18th Flr. Trident Tower";
};
Emails = {
value = "careers@drakepersonnel.com.ph";
};
Office = {
value = Makati;
};
Tel = {
value = "02-7532490";
};
latitude = {
value = "14.56213";
};
longitude = {
value = "121.02437";
};
name = {
value = "Drake Makati";
};
postcode = {
value = 1200;
};
value = "";
};
value = "";
};
}
What i want from the parser (some of the tags arent the same…im aware)
(
{
Address = "1904B 19th Floor West Tower, Philippine Stock Exchange Centre, Exchange Road, Ortigas Center, Pasig City 1600";
Emails = "clients@drakepersonnel.com.ph";
Fax = "632 753 1524 loc 106";
GeoLocation = "14.58273, 121.06154";
Office = Philippines;
Tel = "632 753 1522-24 / 632 753 2490-93";
}
)
Here is the XMLreader.m file im using
//
// XMLReader.m
//
// Created by Troy on 9/18/10.
// Updated by Antoine Marcadet on 9/23/11.
//
#import "XMLReader.h"
NSString *const kXMLReaderTextNodeKey = @"value";
NSString *const kXMLReaderAttributePrefix = @"@";
@interface XMLReader ()
- (id)initWithError:(NSError **)error;
- (NSDictionary *)objectWithData:(NSData *)data options:(XMLReaderOptions)options;
@end
@implementation XMLReader
#pragma mark -
#pragma mark Public methods
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
{
XMLReader *reader = [[XMLReader alloc] initWithError:error];
NSDictionary *rootDictionary = [reader objectWithData:data options:0];
[reader release];
return rootDictionary;
}
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [XMLReader dictionaryForXMLData:data error:error];
}
+ (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(XMLReaderOptions)options error:(NSError **)error
{
XMLReader *reader = [[XMLReader alloc] initWithError:error];
NSDictionary *rootDictionary = [reader objectWithData:data options:options];
[reader release];
return rootDictionary;
}
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(XMLReaderOptions)options error:(NSError **)error
{
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [XMLReader dictionaryForXMLData:data options:options error:error];
}
#pragma mark -
#pragma mark Parsing
- (id)initWithError:(NSError **)error
{
if (self = [super init])
{
errorPointer = error;
}
return self;
}
- (void)dealloc
{
[dictionaryStack release];
[textInProgress release];
[super dealloc];
}
- (NSDictionary *)objectWithData:(NSData *)data options:(XMLReaderOptions)options
{
// Clear out any old data
[dictionaryStack release];
[textInProgress release];
dictionaryStack = [[NSMutableArray alloc] init];
textInProgress = [[NSMutableString alloc] init];
// Initialize the stack with a fresh dictionary
[dictionaryStack addObject:[NSMutableDictionary dictionary]];
// Parse the XML
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setShouldProcessNamespaces:(options & XMLReaderOptionsProcessNamespaces)];
[parser setShouldReportNamespacePrefixes:(options & XMLReaderOptionsReportNamespacePrefixes)];
[parser setShouldResolveExternalEntities:(options & XMLReaderOptionsResolveExternalEntities)];
parser.delegate = self;
BOOL success = [parser parse];
[parser release];
// Return the stack's root dictionary on success
if (success)
{
NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
return resultDict;
}
return nil;
}
#pragma mark -
#pragma mark NSXMLParserDelegate methods
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// Get the dictionary for the current level in the stack
NSMutableDictionary *parentDict = [dictionaryStack lastObject];
// Create the child dictionary for the new element, and initilaize it with the attributes
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
[childDict addEntriesFromDictionary:attributeDict];
// If there's already an item for this key, it means we need to create an array
id existingValue = [parentDict objectForKey:elementName];
if (existingValue)
{
NSMutableArray *array = nil;
if ([existingValue isKindOfClass:[NSMutableArray class]])
{
// The array exists, so use it
array = (NSMutableArray *) existingValue;
}
else
{
// Create an array if it doesn't exist
array = [NSMutableArray array];
[array addObject:existingValue];
// Replace the child dictionary with an array of children dictionaries
[parentDict setObject:array forKey:elementName];
}
// Add the new child dictionary to the array
[array addObject:childDict];
}
else
{
// No existing value, so update the dictionary
[parentDict setObject:childDict forKey:elementName];
}
// Update the stack
[dictionaryStack addObject:childDict];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// Update the parent dict with text info
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];
// Set the text property
if ([textInProgress length] > 0)
{
// trim after concatenating
NSString *trimmedString = [textInProgress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[dictInProgress setObject:[[trimmedString mutableCopy] autorelease] forKey:kXMLReaderTextNodeKey];
// Reset the text
[textInProgress release];
textInProgress = [[NSMutableString alloc] init];
}
// Pop the current dict
[dictionaryStack removeLastObject];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// Build the text value
[textInProgress appendString:string];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
// Set the error pointer to the parser's error object
*errorPointer = parseError;
}
@end
Any Help would be appreciated.
where is the problem to just select the values you need out of the resulting dictionary of the XML parser? If you know the XML element names you could easily do something like:
Also I’d expect that the XML element
officescould contain more than a single office, so you would simply collect allofficedictionaries out of theofficesarray.Cheers,
anka