How to get the name and value of attributes from x

2019-03-30 23:08发布

问题:

I got stuck on trying to detect the pair of name and value of the attributes in some general xmls by using libxml2 for parsing the api on iPhone application. For my project, the parsing speed is really important, so I decided to use libxml2 itself instead of using NSXMLParser.

Now, as referring to XMLPerformance that is a sample of iPhone SDK for the parsing benchmark between NSXMLParser and libxml2, I tried to get the detail of attribute in one of XML parser handler as below, but I don't know exactly how to detect it.

/* for example, <element key="value" /> */
static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix,
const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes,
int nb_defaulted, const xmlChar **attributes)
{
    if (nb_attributes > 0)
    {
        NSMutableDictionary* attributeDict = [NSMutableDictionary dictionaryWithCapacity:(NSUInteger)[NSNumber numberWithInt:nb_attributes]];
        for (int i=0; i<nb_attributes; i++)
        {
            NSString* key = @""; /* expected: key */
            NSString* val = @""; /* expected: value */
            [attributeDict setValue:val forKey:key];
        }
     }
}

I saw the libxml2 document, but I can't. Please help me if you are great hacker :)

回答1:

From looking at the linked documentation I'd think something like this might work:

    for (int i=0; i<nb_attributes; i++) 
    { 
        // if( *attributes[4] != '\0' ) // something needed here to null terminate the value
        NSString* key = [NSString stringWithCString: attributes[0] encoding: xmlencoding];
        NSString* val = [NSString stringWithCString: attributes[3] encoding: xmlencoding];
        [attributeDict setValue:val forKey:key];
        attributes += 5;
    } 

This assumes that there are always 5 string pointers for each attribute. As it is not otherwise noted I think it is safe to assume that the value string is null terminated and the end pointer is only given to allow easy length calculation. In case the end pointer does not point to a null char you would need to interpret only the chars from attributes[3] up to attributes[4] as value string (length = attributes[4]-attributes[3]).

xmlencoding probably needs to be the encoding of the xml document/entity except libxml2 does some conversion already although this seems unlikely as it typedefs xmlChar to unsigned char.



回答2:

For Others, based on x4u answer and tksohishi comment:

 static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
                                         int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes)
 {

        NSLog(@"localname = %s",localname);

        if(nb_attributes>0)
        {
            NSMutableDictionary * attributeDict =[[NSMutableDictionary alloc] initWithCapacity:nb_attributes];

            for (int i=0; i<nb_attributes; i++)
            {

                NSString* key = [NSString stringWithCString:(const char*)attributes[0] encoding:NSUTF8StringEncoding];
                NSString* val = [[NSString alloc] initWithBytes:(const void*)attributes[3] length:(attributes[4] - attributes[3]) encoding:NSUTF8StringEncoding]; // it'll be required // [val release];
                [attributeDict setValue:val forKey:key];
                attributes += 5;
            }
        }
 }