从xml文件中读取内容并存储在数组中

时间:2013-09-23 04:42:37

标签: c libxml2

我第一次使用xml并且在将xml文件的内容存储到数组中时遇到了一些问题。我使用libxml2来解析xml文件,并且我能够获取数据并能够打印它。代码如下:

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

wchar_t buffer[7][50]={"\0"};

static void parseDoc(const char *docname) 
{

    xmlDocPtr doc;
    xmlNodePtr cur;
    xmlChar *key;
    int i=0;
    doc = xmlParseFile(docname);

    if (doc == NULL ) {

    fprintf(stderr,"Document not parsed successfully. \n");
     return;
    }

    cur = xmlDocGetRootElement(doc);

    if (cur == NULL) 
    {
      fprintf(stderr,"empty document\n");
      xmlFreeDoc(doc);
      return;
    }

    cur = cur->xmlChildrenNode;

    while (cur != NULL) 
    {
        key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
        wmemcpy(buffer[i],(wchar_t*)(key),size(key));   /*segmentation fault at this stage*/        
        printf("Content : %s\n", key);
        xmlFree(key);
        i++;
        cur = cur->next;
    }
    xmlFreeDoc(doc);
    return;
}

int main(void) 
{
   const char *docname="/home/workspace/TestProject/Text.xml;
   parseDoc (docname);
   return (1);
 }

示例xml文件在

下面提供
 <?xml version="1.0"?>
 <story>
  <author>John Fleck</author>
  <datewritten>June 2, 2002</datewritten>
  <keyword>example keyword</keyword>
  <headline>This is the headline</headline>
  <para>This is the body text.</para>
 </story>

在屏幕上打印时文件内容的输出如下

Content : null

Content : John Fleck

Content : null

Content : June 2, 2002

Content : null

Content : example keyword

Content : null

Content : This is the headline

Content : null

Content : This is the body text.

我觉得文件的内容在很少的地方都是空的,这导致了复制中的问题,从而产生了分段错误。请让我知道如何解决问题,有没有更好的方法来完成这件事。我使用MSXML解析器读取了类似的xml文件,这是我第一次使用Linux API。

编辑复制部分如下所示,但是wchart阵列的内容是乱码。我们将不胜感激。

while (cur != NULL) {

    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
    if(key!=NULL)
    {
        wmemcpy(DiscRead[i],(const wchar_t *)key,sizeof(key));
        i++;
    }

    printf("keyword: %s\n", key);
    xmlFree(key);

    cur = cur->next;
}

2 个答案:

答案 0 :(得分:1)

buffer数组不够大。将缓冲区大小增加到buffer[7+3][50]

wchar_t buffer[7][50]={"\0"};
...
while (cur != NULL) {
  wmemcpy(buffer[i],(wchar_t*)(key),size(key));   /*segmentation fault */
  printf("Content : %s\n", key);
  ...
  i++;
}

输出为10行&#34;内容:...&#34;。因此i从0增加到9.但是buffer可能只被索引为0到6.索引7及更高版本是未定义的行为,这最终表现为段错误。

答案 1 :(得分:1)

您的代码有多个问题:

  • 您使用wchar_t作为字符串数组。这不适合您从libxml2获得的UTF-8编码字符串。您应该坚持使用xmlChar或使用char
  • 使用xmlNodeListGetString获取通过cur->xmlChildrenNode作为节点列表的节点的文本内容。对于文本节点,后者将为NULL,因此xmlNodeListGetString将返回NULL作为错误条件。您只需在当前节点上调用xmlNodeGetContent,但前提是它只是一个元素节点。
  • 不建议使用xmlChildrenNode作为字段名称。您应该使用children
  • 拨打wmemcpy是危险的。我建议像strlcpy更安全。

尝试这样的事情:

char buffer[7][50];

static void parseDoc(const char *docname)
{
    xmlDocPtr doc;
    xmlNodePtr cur;
    xmlChar *key;
    int i = 0;
    doc = xmlParseFile(docname);

    if (doc == NULL) {
        fprintf(stderr, "Document not parsed successfully. \n");
        return;
    }

    cur = xmlDocGetRootElement(doc);

    if (cur == NULL) {
        fprintf(stderr, "empty document\n");
        xmlFreeDoc(doc);
        return;
    }

    for (cur = cur->children; cur != NULL; cur = cur->next) {
        if (cur->type != XML_ELEMENT_NODE)
            continue;
        key = xmlNodeGetContent(cur);
        strlcpy(buffer[i], key, 50);
        printf("Content : %s\n", key);
        xmlFree(key);
        i++;
    }

    xmlFreeDoc(doc);
}

您还应该检查i是否超出了数组中字符串的数量。