C 如何从libxml2中的节点获取属性

C 如何从libxml2中的节点获取属性,c,libxml2,C,Libxml2,我正在使用解析器从XML文件中获取数据。我使用libxml2来提取数据。我无法从节点获取属性。我只找到了nb\u属性,以获取属性的计数。尝试以下方法: xmlNodePtr node; // Some node NSMutableArray *attributes = [NSMutableArray array]; for(xmlAttrPtr attribute = node->properties; attribute != NULL; attribute = attribute-&

我正在使用解析器从XML文件中获取数据。我使用libxml2来提取数据。我无法从节点获取属性。我只找到了
nb\u属性
,以获取属性的计数。

尝试以下方法:

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

我认为joostk的意思是属性->孩子,给予这样的东西:

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

看看这是否对您有效。

如果您只需要一个属性,请使用或

我想我找到了为什么您只获得了一个属性(至少在我身上是这样)

问题是我读取了第一个节点的属性,但下一个节点是文本节点。不知道为什么,但是node->properties给了我一个对内存中不可读部分的引用,所以它崩溃了

我的解决方案是检查节点类型(元素为1)

我用的是阅读器,所以:

xmlTextReaderNodeType(reader)==1
您可以从中获取整个代码并添加此

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方法startElements(…),则此函数就是您要查找的:

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

我发现使用libxml2(通过C++中的libxml++)最简单的方法是使用
eval_to_XXX
方法。它们计算XPath表达式,因此需要使用
@property
语法

例如:

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

嗨,马特。我发现您的代码有助于查找属性的值。但它只给出第一个节点的值。如何获取以下节点的值??。。提前感谢。您可以像迭代属性一样迭代节点:node=node->next.Hi Mat。我发现您的代码有助于查找属性的值。但它只给出第一个节点的值。如何获取以下节点的值??。。提前感谢。
节点子节点
不应该变成
属性->子节点
?是的,应该:)也请看@Matthew Lowe,他之前注意到了错误。我已经更新了答案(2.5年后;))libxml++更有效、更直接的方法是
returnstd::string(dynamic_cast(node)->get_attribute_value(“property”)
。另外,您的参数声明也很奇怪:您将
节点
声明为指向非常量
xmlpp::node
的常量指针的引用。更有用的是:
constxmlpp::Node*Node
std::string get_property(xmlpp::Node *const &node) {
    return node->eval_to_string("@property")
}