【问题标题】:How to get attributes from a node in libxml2如何从 libxml2 中的节点获取属性
【发布时间】:2010-11-08 16:46:06
【问题描述】:

我正在使用解析器从 XML 文件中获取数据。我正在使用 libxml2 来提取数据。我无法从节点获取属性。我只找到nb_attributes 来获取属性的数量。

【问题讨论】:

    标签: c 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);
    }
    

    【讨论】:

    • 嗨,垫子。我发现您的代码有助于找出属性的值。但它只给出了第一个节点的值。如何获取以下节点的值。 ??..提前谢谢。
    • 不应该把node-children变成attribute->children吗?
    • 是的,它应该 :) 另见@Matthew Lowe,他早些时候注意到了这个错误。我已经更新了答案(2.5 年后;))
    【解决方案2】:

    我认为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;
    }
    

    看看这是否适合你。

    【讨论】:

    • 嗨,垫子。我发现您的代码有助于找出属性的值。但它只给出了第一个节点的值。如何获取以下节点的值。 ??..提前谢谢。
    • 您可以像遍历属性一样遍历节点:node = node->next.
    【解决方案3】:

    如果您只想要一个属性,请使用xmlGetProp 或xmlGetNsProp

    【讨论】:

      【解决方案4】:

      我想我找到了为什么你只有 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 行。

      【讨论】:

        【解决方案5】:

        如果你使用 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);
        

        【讨论】:

          【解决方案6】:

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

          例如:

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

          【讨论】:

          • 使用 libxml++ 更有效、更直接的方法是return std::string(dynamic_cast&lt;const xmlpp::Element*&gt;(node)-&gt;get_attribute_value("property"))。此外,您的参数声明很奇怪:您将 node 声明为对指向非 const xmlpp::Node 的 const 指针的引用。更有用的是:const xmlpp::Node *node
          猜你喜欢
          • 1970-01-01
          • 2012-05-08
          • 1970-01-01
          • 2011-01-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-07-01
          相关资源
          最近更新 更多