2009-07-07 10 views
6

Tôi đang làm việc trên một trình phân tích cú pháp để lấy dữ liệu từ một tệp XML. Tôi đang sử dụng libxml2 để trích xuất dữ liệu. Tôi không thể lấy các thuộc tính từ các nút. Tôi chỉ tìm thấy nb_attributes để nhận số lượng thuộc tính.Cách lấy thuộc tính từ một nút trong libxml2

Trả lời

1

Hãy thử một cái gì đó như:

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

Hi Mat. Tôi thấy mã của bạn hữu ích trong việc tìm ra các giá trị của thuộc tính. Nhưng nó chỉ cung cấp giá trị cho nút đầu tiên. Cách lấy giá trị cho các nút sau đây. ??.. Cảm ơn trước. – NiKKi

+0

Không nên 'node-children' trở thành' thuộc tính-> trẻ em'? –

+0

Có nó nên :) Cũng thấy @Matthew Lowe, anh ta nhận thấy sai lầm trước đó. Tôi đã cập nhật câu trả lời (2.5 năm sau;)) – Joost

8

Tôi nghĩ joostk nghĩa attribute-> trẻ em, tạo cho một cái gì đó như thế này:

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

Xem nếu mà làm việc cho bạn.

+0

Hi Mat. Tôi thấy mã của bạn hữu ích trong việc tìm ra các giá trị của thuộc tính. Nhưng nó chỉ cung cấp giá trị cho nút đầu tiên. Cách lấy giá trị cho các nút sau đây. ??.. Cảm ơn trước. – NiKKi

+0

Bạn có thể lặp qua các nút giống như cách bạn lặp qua các thuộc tính: node = node-> next. –

2

Tôi nghĩ rằng tôi đã tìm thấy lý do tại sao bạn chỉ có 1 thuộc tính (ít nhất là nó đã xảy ra với tôi).

Vấn đề là tôi đã đọc thuộc tính cho nút đầu tiên nhưng tiếp theo là nút văn bản. Không biết tại sao, nhưng các thuộc tính node-> cho tôi tham chiếu đến một phần không thể đọc được của bộ nhớ, do đó nó bị hỏng.

giải pháp của tôi là để kiểm tra loại nút (phần tử là 1)

Tôi đang sử dụng một trình đọc, vì vậy:

xmlTextReaderNodeType(reader)==1 

Toàn bộ mã bạn có thể lấy nó từ http://www.xmlsoft.org/examples/reader1.c và thêm

này
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; 
    } 
} 

để lót 50.

0

Nếu bạn sử dụng phương pháp SAX startElementNs (...), chức năng này là những gì bạn đang tìm kiếm:

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

Cách sử dụng:

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

Cách đơn giản nhất tôi thấy sử dụng libxml2 (thông qua libxml ++ trong C++) là sử dụng các eval_to_XXX phương pháp. Chúng đánh giá một biểu thức XPath, vì vậy bạn cần sử dụng cú pháp @property.

Ví dụ:

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

Cách hiệu quả và trực tiếp hơn với libxml ++ là 'return std :: string (dynamic_cast (node) -> get_attribute_value (" property "))'. Ngoài ra, khai báo tham số của bạn là lạ: bạn khai báo 'node' như là một tham chiếu đến một con trỏ const tới non-const' xmlpp :: Node'. Hữu ích hơn sẽ là: 'const xmlpp :: Node * node' – maxschlepzig