Как получить имя и значение атрибутов из xml при использовании парсера libxml2 sax?

Я застрял, пытаясь определить пару имени и значения атрибутов в некоторых общих XML-файлах, используя libxml2 для анализа API в приложении iPhone. Для моего проекта очень важна скорость парсинга, поэтому я решил использовать саму libxml2 вместо использования NSXMLParser.

Теперь, ссылаясь на XMLPerformance, который является образцом iPhone SDK для эталонного анализа синтаксического анализа между NSXMLParser и libxml2, я попытался получить детали атрибута в одном из обработчиков синтаксического анализатора XML, как показано ниже, но я точно не знаю, как его обнаружить .

/* 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];
        }
     }
}

Я видел документ libxml2, но не могу. Пожалуйста, помогите мне, если вы великий хакер :)


person tksohishi    schedule 16.01.2010    source источник
comment
Емкость должна быть uint, а не указателем на объект (NSNumber). т.е. [NSMutableDictionary DictionaryWithCapacity: (NSUInteger) nb_attributes];   -  person Alex Nazarov    schedule 09.10.2011


Ответы (2)


Глядя на связанную документацию, я думаю, что что-то вроде этого может работать:

    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;
    } 

Это предполагает, что для каждого атрибута всегда имеется 5 строковых указателей. Поскольку не указано иное, я думаю, что можно с уверенностью предположить, что строка значения завершается нулем, а конечный указатель дается только для облегчения расчета длины. В случае, если конечный указатель не указывает на нулевой символ, вам нужно будет интерпретировать только символы от атрибутов [3] до атрибутов [4] как строку значения (длина = атрибуты [4] - атрибуты [3]).

xmlencoding, вероятно, должна быть кодировкой XML-документа/объекта, за исключением того, что libxml2 уже выполняет некоторое преобразование, хотя это кажется маловероятным, поскольку он typedefs xmlChar для unsigned char.

person x4u    schedule 16.01.2010
comment
Спасибо, x4u! Наконец, это работает так. Ключ NSString * = [NSString stringWithCString: (const char *) атрибуты [0] кодировка: NSUTF8StringEncoding]; NSString* val = [[NSString alloc] initWithBytes: (const void*) атрибуты [3] длина: (атрибуты [4] - атрибуты [3]) encoding: NSUTF8StringEncoding]; // потребуется // [val release]; - person tksohishi; 19.01.2010

Для других, на основе ответа x4u и комментария tksohishi:

 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;
            }
        }
 }
person user1105951    schedule 11.11.2018