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
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);
}
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.
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
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. –
nếu bạn chỉ muốn một thuộc tính duy nhất, sử dụng xmlGetProp hoặc xmlGetNsProp
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àyxmlNodePtr 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.
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);
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")
}
Cách hiệu quả và trực tiếp hơn với libxml ++ là 'return std :: string (dynamic_cast
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
Không nên 'node-children' trở thành' thuộc tính-> trẻ em'? –
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