【问题标题】:XML Parsing with libxml in C is not showing attribute name在 C 中使用 libxml 进行 XML 解析未显示属性名称
【发布时间】:2014-11-30 16:58:10
【问题描述】:

我正在尝试解析 XHTML 文件并获取属性及其值。使用 libxml。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/HTMLparser.h>
#include <libxml/xmlmemory.h> 
#include <libxml/tree.h>
#include <libxml/parser.h>

void walkTree(xmlNode * a_node)
{
  xmlNode *cur_node = NULL;
  xmlAttr *cur_attr = NULL;
  for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
     // do something with that node information, like… printing the tag’s name and attributes
     printf("Got tag : %s\n", cur_node->name);
     for (cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
     printf("  -> with attribute : %s\n", cur_attr->name);
     printf("     -> with Value: %s\n", (cur_attr->children)->name);
}
walkTree(cur_node->children);
}
}
int main(void)
{  
// Load XHTML
char *data;
data = "<html><body class=\"123\" damn=\"123\"></html>";

int len = strlen(data) + 1;
htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, 0);
htmlCtxtUseOptions(parser, HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET);
htmlParseChunk(parser, data, len, 0);
htmlParseChunk(parser, NULL, len, 1);
walkTree(xmlDocGetRootElement(parser->myDoc));

 }

我期待这个输出

 Got tag: html
Got tag: body
-> with attribute: class
  -> with value: 123
-> with attribute: damn
  -> with value: 123

但不幸的是,我得到了这个输出:

 Got tag: html
Got tag: body
-> with attribute: class
  -> with value: text
-> with attribute: damn
  -> with value: text

我也尝试过其他html代码,无论属性值是什么,它总是显示“文本”而不​​是值。

为什么?如何解决?如何获取真实的属性值?

【问题讨论】:

    标签: c parsing xhtml libxml2


    【解决方案1】:

    这可以很容易地通过修改一行代码来实现。xmlNodeGetContent() 因为它接受 xmlNode。与接受 xmlNodePtr 的 xmlGetProp() 不同。所以在使用 xmlNode 或 xmlAttr 时最好使用 xmlNodeGetContent() 来获取节点的属性.希望有帮助:)

    解决办法如下:

     #include <stdio.h>
     #include <string.h>
     #include <stdlib.h>
     #include <libxml/HTMLparser.h>
     #include <libxml/xmlmemory.h>
     #include <libxml/tree.h>
     #include <libxml/parser.h>
     void walkTree(xmlNode * a_node)
     {
        xmlNode *cur_node = NULL;
        xmlAttr *cur_attr = NULL;
        xmlChar *attr;
        for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
        // do something with that node information, like… printing the tag’s name and attributes
        printf("Got tag : %s\n", cur_node->name);
        for (cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
    
           printf("  -> with attribute : %s\n", cur_attr->name);
    
           // This part fixed the code :D 
           attr =  xmlNodeGetContent(cur_attr);
    
          printf("     -> with Value: %s\n", attr);
        }
       walkTree(cur_node->children);
    }
    }
    int main(void)
    {
    // Load XHTML
    char *data;
    data = "<html><body class=\"123\" damn=\"123\"></html>";
    
        int len = strlen(data) + 1;
        htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, 0);
         htmlCtxtUseOptions(parser, HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | HTML_PARSE_NOWARNING | HTML_PARSE_NONET);
         htmlParseChunk(parser, data, len, 0);
         htmlParseChunk(parser, NULL, len, 1);
         walkTree(xmlDocGetRootElement(parser->myDoc));
    
    }
    

    【讨论】:

      【解决方案2】:

      与其直接在属性结构中戳,不如用xmlGetProp,按照here的方法:

      void
      getReference (xmlDocPtr doc, xmlNodePtr cur) {
      
          xmlChar *uri;
          cur = cur->xmlChildrenNode;
          while (cur != NULL) {
              if ((!xmlStrcmp(cur->name, (const xmlChar *)"reference"))) {
                  uri = xmlGetProp(cur, "uri");
                  printf("uri: %s\n", uri);
                  xmlFree(uri);
              }
              cur = cur->next;
          }
          return;
      }
      

      我认为正在发生的是属性节点的子节点是一个文本节点,其中文本作为 contents 而不是名称。但是使用提供的 API 将对您隐藏所有这些。并且还提供一些错误检查(例如,如果childrenNULL)。

      【讨论】:

      • 它没有工作它尝试过,因为在我的代码中它将通过 XmlNode 但它需要 XmlNodePtr。
      • XmlNodestructXmlNodePtr 只是指向 struct 的指针。
      【解决方案3】:

      Khaled 对答案的小修正:

       void walkTree(xmlNode * a_node)
       {
          xmlNode *cur_node = NULL;
          xmlAttr *cur_attr = NULL;
          xmlChar *attr;
          for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
          // do something with that node information, like… printing the tag’s name and attributes
          printf("Got tag : %s\n", cur_node->name);
          for (cur_attr = cur_node->properties; cur_attr; cur_attr = cur_attr->next) {
      
             printf("  -> with attribute : %s\n", cur_attr->name);
      
             // CORRECTION HERE
             attr =  xmlNodeGetContent(cur_attr->children);
      
            printf("     -> with Value: %s\n", attr);
          }
         walkTree(cur_node->children);
      }
      }
      

      如果没有这个,它将为同一标签中的不同属性打印相同的属性值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-23
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        相关资源
        最近更新 更多