【发布时间】:2010-11-08 16:46:06
【问题描述】:
我正在使用解析器从 XML 文件中获取数据。我正在使用 libxml2 来提取数据。我无法从节点获取属性。我只找到nb_attributes 来获取属性的数量。
【问题讨论】:
我正在使用解析器从 XML 文件中获取数据。我正在使用 libxml2 来提取数据。我无法从节点获取属性。我只找到nb_attributes 来获取属性的数量。
【问题讨论】:
尝试类似:
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);
}
【讨论】:
node-children变成attribute->children吗?
我认为joostk的意思是attribute->children,给出这样的东西:
xmlAttr* attribute = node->properties;
while(attribute)
{
xmlChar* value = xmlNodeListGetString(node->doc, attribute->children, 1);
//do something with value
xmlFree(value);
attribute = attribute->next;
}
看看这是否适合你。
【讨论】:
如果您只想要一个属性,请使用xmlGetProp 或xmlGetNsProp
【讨论】:
我想我找到了为什么你只有 1 个属性(至少它发生在我身上)。
问题是我读取了第一个节点的属性,但下一个是文本节点。不知道为什么,但是 node->properties 给了我一个对内存不可读部分的引用,所以它崩溃了。
我的解决方案是检查节点类型(元素为 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 行。
【讨论】:
如果你使用 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);
【讨论】:
我发现使用 libxml2(通过 C++ 中的 libxml++)最简单的方法是使用 eval_to_XXX 方法。它们评估 XPath 表达式,因此您需要使用 @property 语法。
例如:
std::string get_property(xmlpp::Node *const &node) {
return node->eval_to_string("@property")
}
【讨论】:
return std::string(dynamic_cast<const xmlpp::Element*>(node)->get_attribute_value("property"))。此外,您的参数声明很奇怪:您将 node 声明为对指向非 const xmlpp::Node 的 const 指针的引用。更有用的是:const xmlpp::Node *node