xmlNewChild并不总是写入元素的值

时间:2013-11-23 20:10:57

标签: c xml libxml2

我使用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会检查变量的类型,并在xmlNewChild显示变量的正确值之前将其强制转换为xmlChar和printf。

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>

1 个答案:

答案 0 :(得分:0)

我不确定为什么,但我必须使用

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

使用xmlNewChild之后。

我不确定这个解决方案(它不是最好的解决方案)但它确实可以解决问题。

如果我能对上述行为做出解释,我仍然感激不尽。