使用libxml2的xmlNewChild函数出现一个非常奇怪的错误。我试图使帖子尽可能短,所以删除了一些无关紧要的逻辑。为要写入的每个变量定义一个布尔变量,并且在设置变量值时,该布尔值设置为TRUE,指示是否存在标签,如果存在,则将其写入,否则将被跳过

我定义的结构如下:

 tyedef struct _xml_parse_t
 {
    const char   *name;
    void         *variable;
    int          type;
    _xml_parse_t *childs;
 } xml_parse_t;


另一个函数解析此结构并将其写入char *。该函数定义如下:

int generate_xml(xml_parse_t *p, char *out, const char*root)
{
    xmlChar *s = NULL;
    int size = 0;

    xmlDocPtr doc = NULL;
    xmlNodePtr root_node = NULL;

    doc = xmlNewDoc(NULL);
    if(NULL == doc)
        return -1;
    root_node = xmlNewNode(NULL, BAD_CAST root);
    if(NULL == root_node)
        return -1;
    else
        xmlDocSetRootElement(doc, root_node);

    if(-1 == writeXmlToDoc(p, doc, root_node))
        return -1;

    xmlDocDumpFormatMemoryEnc(doc, &s, &size, "UTF-8", 1);

    if(NULL == s)
        return -1;

    if(SUCCEED == ret)
        strcpy(out, (char *)s);

    if(NULL != s)
        xmlFree(s);

    xmlFreeDoc(doc);
    xmlCleanupParser();
    xmlMemoryDump();

    return 0;
}


writeXmlToDoc定义如下

int writeXmlToDoc(xml_parse_t *parse, xmlDocPtr doc,
            xmlNodePtr root_node)
{
    xml_parse_t *p = parse;
    xmlNodePtr node;

    while(NULL != p->name)
    {
        if( NODE_TYPE_PARENT == p->type && NULL != p->childs)
        {
            node = xmlNewChild(root_node, NULL, BAD_CAST p->name, NULL);
            if(-1 == writeXmlToDoc(p->childs, doc, node))
                return -1;
        }
        else
        {
            printf("Current value being written [%s]", (char *)cvtToXmlChar(p->variable, p->type));
            node = xmlNewChild(root_node, NULL, BAD_CAST p->name,
                BAD_CAST cvtToXmlChar(p->variable, p->type));

        }
        p++;
    }

    return 0;
}


为了使这篇文章尽可能简短,cvtToXmlChar检查变量的类型并将其强制转换为xmlChar和printf,然后xmlNewChild显示正确的变量值。

xml_parse_t child_parse[] = {
   /* Name           var          Type              Childs*/
    {"ChildInt",     &test_int1,   NODE_TYPE_INT,    NULL },
    {"ChildLong",    &test_long1,  NODE_TYPE_LONG,   NULL },
    {"ChildChar",    test_char1,  NODE_TYPE_STRING, NULL },
    {"ChildShort",   &test_short1, NODE_TYPE_SHORT,  NULL },
    {"ChildDouble",  &test_double1,NODE_TYPE_DOUBLE, NULL },
    { NULL }
};

xml_parse_t parent_parse[] = {
   /* Name           var          Type              Childs*/
    {"ParentInt",    &test_int,    NODE_TYPE_INT,    NULL        },
    {"ParentLong",   &test_long,   NODE_TYPE_LONG,   NULL        },
    {"ParentChar",   test_char,   NODE_TYPE_STRING, NULL        },
    {"ParentShort",  &test_short,  NODE_TYPE_SHORT,  NULL        },
    {"ParentDouble", &test_double, NODE_TYPE_DOUBLE, NULL        },
    {"ParentParent", NULL,        NODE_TYPE_PARENT, child_parse },
    { NULL }
};


变量设置如下:

 test_int = 1;
 test_int1 = 2;
 test_long = 1;
 test_long1 = 2;
 sprintf(test_char, "TestParentCharTag");
 sprintf(test_char1, "TestChildCharTag");
 test_short = 1;
 test_short1 = 2;
 test_double = 1;
 test_double1 = 2;


问题是,输出字符串缺少2个值。以下是运行测试的输出

 <ROOTELEMENT>
   <ParentInt>1</ParentInt>
   <ParentLong></ParentLong>
   <ParentChar>TestParentCharTag</ParentChar>
   <ParentShort>1</ParentShort>
   <ParentDouble>1.000000</ParentDouble>
   <ParentParent>
     <ChildInt></ChildInt>
     <ChildLong>2</ChildLong>
     <ChildChar>TestChildCharTag</ChildChar>
     <ChildShort>2</ChildShort>
     <ChildDouble>2.000000</ChildDouble>
   </ParentParent>
 </ROOTELEMENT>

最佳答案

我不确定为什么,但我不得不使用

  xmlNodeSetContent(node, BAD_CAST cvtToXmlChar(variable, type));


使用xmlNewChild之后。

我不确定这种解决方案(这实际上不是最好的解决方案),但确实成功了。

如果能得到上述行为的解释,我仍然感激不尽。

10-05 23:03