0

我第一次使用 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;
}
4

2 回答 2

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 行“内容:...”。因此i从 0 到 9 递增。但buffer只能从 0 到 6 进行索引。索引 7 及更高版本是未定义的行为,这最终表现为段错误。

于 2013-09-23T06:23:44.340 回答
1

您的代码有多个问题:

  • wchar_t用于您的字符串数组。这不适用于您将从 libxml2 获得的 UTF-8 编码字符串。你应该坚持xmlChar或使用char.
  • 您用于xmlNodeListGetString获取cur->xmlChildrenNode作为节点列表传递的节点的文本内容。后者将NULL用于文本节点,因此xmlNodeListGetStringNULL作为错误条件返回。您应该简单地调用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是否超出了数组中的字符串数。

于 2013-09-23T18:34:45.557 回答