TouchXML Empty Node values

343 Views Asked by At

I am trying to parse some XML for an iphone app(IOS5 xcode4.2) I had given up with NSXMLParser as it was a pain to get anywhere. So I went with touchXML, I am able to pull my remote XML file from a web server and see node names but the values of those nodes are blank See code below and sample xml(i have taken out a lot of data) But what i am trying to do is get a NSArray or NSDirectory with the name of the character and subarray or NSDirectory of all the stats the they key being the name of the stat and the value as the value

<apiresponse>
  <character name="testname" ....>
    <vocation name="testvocation" ....>...</vocation>
    <stats>
     <stat name="health" value="1234"/>
     <stat name="power" value="4321"/>
    </stats>
    <equipment>
    </equipment>
  </character>

// Create a new xmlParser object based on the TouchXML "CXMLDocument" class, this is the
// object that actually grabs and processes the xml data
CXMLDocument *xmlParser = [[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil];

// Create a new Array object to be used with the looping of the results from the xmlParser
NSArray *resultNodes = NULL;



// Set the resultNodes Array to contain an object for every instance of an  node in our xml
resultNodes = [xmlParser nodesForXPath:@"apiresponse/character" error:nil];



// Loop through the resultNodes to access each items actual data
    for (CXMLElement *resultElement in resultNodes) {

        // Create a temporary MutableDictionary to store the items fields in, which will eventually end up in stats
        NSMutableDictionary *stat = [[NSMutableDictionary alloc] init];

        // Create a counter variable as type "int"
        int counter;

        // Loop through the children of the current  node
        for(counter = 0; counter < [resultElement childCount]; counter++) {

            // Add each field to the stat Dictionary with the node name as key and node value as the value
            [stat setObject:[[resultElement childAtIndex:counter] stringValue] forKey:    [[resultElement childAtIndex:counter] name]];
        }

        // Add the stat to the global stats Array so that the view can access it.
        [self.stats addObject:[stat copy]];
    }
}

NSLog

2012-01-25 08:27:08.890 test[12815:f803] (
    {
    equipment = "";
    stats = "";
    vocation = "";
}
)
1

There are 1 best solutions below

0
On

In order to pull out information from the node, you'll need to use - (CXMLNode *)attributeForName:(NSString *)name. I've modified your code to print out all of the desired node information:

// Set the xml URL appropriately
NSURL *url = [NSURL URLWithString:@"file:///tmp/tmp.xml"];

// Create a new xmlParser object based on the TouchXML "CXMLDocument" class, this is the
// object that actually grabs and processes the xml data
CXMLDocument *xmlParser = [[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil];

// Create a new Array object to be used with the looping of the results from the xmlParser
NSArray *resultNodes = NULL;

// Set the resultNodes Array to contain an object for every instance of an  node in our xml
resultNodes = [xmlParser nodesForXPath:@"apiresponse/character" error:nil];

// Loop through the resultNodes to access each items actual data
for (CXMLElement *resultElement in resultNodes)
{
    // Print out the initial character 'name' attribute
    NSLog(@"Name: %@, Attribute: %@", [resultElement localName], [[resultElement attributeForName:@"name"] stringValue]);

    // Loop through the children of the current  node
    for(int counter = 0; counter < [resultElement childCount]; counter++)
    {
        NSArray *children = [resultElement elementsForName:[[resultElement childAtIndex:counter] localName]];
        for(int secondcounter = 0; secondcounter < [children count]; secondcounter++)
        {
            CXMLElement *child = [children objectAtIndex:secondcounter];
            // Print out the subsequent layer's 'name' attributes
            NSLog(@"Name: %@, Attribute: %@", [child localName], [[child attributeForName:@"name"] stringValue]);

            // Special case for stats which have more children nodes
            if([[child localName] isEqualToString:@"stats"])
            {
                NSArray *grandchildren = [child elementsForName:@"stat"];

                for(int thirdcounter = 0; thirdcounter < [grandchildren count]; thirdcounter++)
                {
                    CXMLElement *grandchild = [grandchildren objectAtIndex:thirdcounter];
                    // Get all of the stats name's
                    NSLog(@"Name: %@, Attribute: %@", [grandchild localName], [[grandchild attributeForName:@"name"] stringValue]);
                }
            }
        }
    }
}

From NSLog:

2013-12-03 16:51:20.170 Validator[6520:707] Name: character, Attribute: testname
2013-12-03 16:51:20.171 Validator[6520:707] Name: vocation, Attribute: testvocation
2013-12-03 16:51:20.171 Validator[6520:707] Name: stats, Attribute: (null)
2013-12-03 16:51:20.171 Validator[6520:707] Name: stat, Attribute: health
2013-12-03 16:51:20.171 Validator[6520:707] Name: stat, Attribute: power
2013-12-03 16:51:20.172 Validator[6520:707] Name: equipment, Attribute: (null)