2009-07-07 3 views
6

Я работаю над парсером для получения данных из XML-файла. Я использую libxml2 для извлечения данных. Я не могу получить атрибуты из узлов. Я только нашел nb_attributes, чтобы получить количество атрибутов.Как получить атрибуты из узла в libxml2

ответ

1

Попробуйте что-то вроде:

xmlNodePtr node; // Some node 
NSMutableArray *attributes = [NSMutableArray array]; 

for(xmlAttrPtr attribute = node->properties; attribute != NULL; attribute = attribute->next){ 
    xmlChar *content = xmlNodeListGetString(node->doc, attribute->children, YES); 
    [attributes addObject:[NSString stringWithUTF8String:content]]; 
    xmlFree(content); 
} 
+0

Привет Mat. Я нашел ваш код полезным для определения значений атрибута. Но он дает значение только для первого узла. Как получить значения для следующих узлов. ??.. Заранее спасибо. – NiKKi

+0

Не следует ли 'node-children' становиться' атрибутом-> детьми'? –

+0

Да, это должно :) Также см. @Matthew Lowe, он заметил ошибку ранее. Я обновил ответ (2,5 года спустя;)) – Joost

8

Я думаю joostk имел в виду attribute-> детей, давая что-то вроде этого:

xmlAttr* attribute = node->properties; 
while(attribute) 
{ 
    xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1); 
    //do something with value 
    xmlFree(value); 
    attribute = attribute->next; 
} 

Смотрите, если это работает для вас.

+0

Hi Mat. Я нашел ваш код полезным для определения значений атрибута. Но он дает значение только для первого узла. Как получить значения для следующих узлов. ??.. Заранее спасибо. – NiKKi

+0

Вы можете перебирать узлы так же, как итерации по атрибутам: node = node-> next. –

2

Я думаю, что я нашел, почему вы получили только 1 атрибут (по крайней мере, это случилось со мной).

Проблема заключалась в том, что я читал атрибуты для первого узла, а затем был текстовым узлом. Не знаю, почему, но свойства node-> дают мне ссылку на неотчитываемую часть памяти, поэтому она разбилась.

Мое решение было проверить тип узла (элемент 1)

Я использую читателя, так:

xmlTextReaderNodeType(reader)==1 

Весь код, который вы можете получить его из http://www.xmlsoft.org/examples/reader1.c и добавить

xmlNodePtr node= xmlTextReaderCurrentNode(reader); 
if (xmlTextReaderNodeType(reader)==1 && node && node->properties) { 
    xmlAttr* attribute = node->properties; 
    while(attribute && attribute->name && attribute->children) 
    { 
     xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1); 
     printf ("Atributo %s: %s\n",attribute->name, value); 
     xmlFree(value); 
     attribute = attribute->next; 
    } 
} 

к линии 50.

0

При использовании метода SAX startElementNs (...), эта функция является то, что вы ищете:

xmlChar *getAttributeValue(char *name, const xmlChar ** attributes, 
      int nb_attributes) 
{ 
int i; 
const int fields = 5; /* (localname/prefix/URI/value/end) */ 
xmlChar *value; 
size_t size; 
for (i = 0; i < nb_attributes; i++) { 
    const xmlChar *localname = attributes[i * fields + 0]; 
    const xmlChar *prefix = attributes[i * fields + 1]; 
    const xmlChar *URI = attributes[i * fields + 2]; 
    const xmlChar *value_start = attributes[i * fields + 3]; 
    const xmlChar *value_end = attributes[i * fields + 4]; 
    if (strcmp((char *)localname, name)) 
     continue; 
    size = value_end - value_start; 
    value = (xmlChar *) malloc(sizeof(xmlChar) * size + 1); 
    memcpy(value, value_start, size); 
    value[size] = '\0'; 
    return value; 
} 
return NULL; 
} 

Использование:

char * value = getAttributeValue("atrName", attributes, nb_attributes); 
// do your magic 
free(value); 
0

Самый простой способ я нашел, используя libxml2 (через Libxml ++ в C++) был использовать eval_to_XXX методы. Они оценивают выражение XPath, поэтому вам нужно использовать синтаксис @property.

Например:

std::string get_property(xmlpp::Node *const &node) { 
    return node->eval_to_string("@property") 
} 
+0

Более эффективным и прямым способом с libxml ++ является 'return std :: string (dynamic_cast (node) -> get_attribute_value (" свойство "))'. Кроме того, объявление параметра является странным: вы объявляете 'node' в качестве ссылки на указатель const на не-const' xmlpp :: Node'. Более полезным будет: 'const xmlpp :: Node * node' – maxschlepzig

Смежные вопросы