C libxml2 xmlTextWriter标记随机嵌套

C libxml2 xmlTextWriter标记随机嵌套,c,libxml2,xmlwriter,xmltextwriter,C,Libxml2,Xmlwriter,Xmltextwriter,我有一个试图保存为xml的结构,它似乎在创建小xml时没有问题,但是在较大文件的情况下,它似乎嵌套了后面的标记,对于前30个左右,我得到了正确的格式结果: <argument><kind>2</kind><string>video.avi</string></argument><argument><kind>4</kind><string>0</string><

我有一个试图保存为xml的结构,它似乎在创建小xml时没有问题,但是在较大文件的情况下,它似乎嵌套了后面的标记,对于前30个左右,我得到了正确的格式结果:

<argument><kind>2</kind><string>video.avi</string></argument><argument><kind>4</kind><string>0</string></argument>
<argument><kind>5</kind><string/><argument><kind>2</kind><string>sprite.gif</string></argument></argument>

很抱歉,我无法将它放在这篇文章的正文中,因为它超过了字符限制。

如果您能提供帮助,我将不胜感激。我已经研究这个错误4个小时了,我似乎找不到任何其他人有这个问题,更不用说修复了。

如果将其传递为NULL,xmlTextWriterWriteElement()将无法正常工作。在调用API或使用xmlTextWriterWriteFormatElement()和%s作为格式之前,请验证字符串是否为NULL

调试器告诉您什么。此外,您还需要考虑使用像Valgrind()这样的内存管理器来运行代码。我甚至不知道在调试器(GDB)中我应该寻找什么信息。但当我这样做的时候,问题就消失了。另外,我忘了提到:这可能不是结构本身的问题,因为我可以从程序中很好地浏览整个树。xmlTextWriterEndElement()返回一个值,因此如果该值为负值,则可以看到它失败的原因。您还可以使用诸如XMLGenericeErrorFunc()之类的API调用为libxml2设置错误处理程序。我使用libxml2已经有一段时间了,但我记得在处理空值时遇到了问题。您确定输出中的空字符串不是由数据中的NULL引起的吗?
//Save an obiect as in xml/gm format
int save_obj(struct gm_object obj, char *file_str)
{
  xmlTextWriterPtr writer;
  xmlChar *tmp;
  // Create a new XmlWriter for uri, with no compression.
  writer = xmlNewTextWriterFilename(file_str, 0);
  if (writer == NULL)
  {
    return 1; //1 = error
  }
  xmlTextWriterStartDocument(writer, NULL, "UTF-8", "no");
  //Root
  xmlTextWriterStartElement(writer, BAD_CAST "object");
  xmlTextWriterWriteElement(writer, BAD_CAST "spriteName", BAD_CAST obj.spriteName);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "solid","%i",obj.solid);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "visible","%i",obj.visible);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "depth","%i",obj.depth);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "persistent","%i",obj.persistent);
  xmlTextWriterWriteElement(writer, BAD_CAST "maskName", BAD_CAST obj.maskName);
  xmlTextWriterWriteElement(writer, BAD_CAST "parentName", BAD_CAST obj.parentName);
  xmlTextWriterStartElement(writer, BAD_CAST "events");
  //This is where we store any ints that need to be converted to strings
  char str_int_converted[(CHAR_BIT * sizeof(int) - 1) / 3 + 2];
  int i;
  for (i = 0; i<obj.event_count-1;i++)
  {
    xmlTextWriterStartElement(writer, BAD_CAST "event");
    sprintf(str_int_converted, "%d", obj.events[i].enumb);
    xmlTextWriterWriteAttribute(writer, BAD_CAST "enumb", BAD_CAST str_int_converted);
    sprintf(str_int_converted, "%d", obj.events[i].eventtype);
    xmlTextWriterWriteAttribute(writer, BAD_CAST "eventtype", BAD_CAST str_int_converted);
    int ii;
    for (ii = 0; ii<obj.events[i].action_count-1;ii++)
    {
      xmlTextWriterStartElement(writer, BAD_CAST "action");
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "libid", "%i", obj.events[i].actions[ii].libid);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "id","%i", obj.events[i].actions[ii].id);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "kind","%i", obj.events[i].actions[ii].kind);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "userelative","%i", obj.events[i].actions[ii].userelative);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "useapplyto", "%i", obj.events[i].actions[ii].useapplyto);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "isquestion", "%i", obj.events[i].actions[ii].isquestion);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "exetype","%i", obj.events[i].actions[ii].exetype);
      xmlTextWriterWriteElement(writer, BAD_CAST "functionname", BAD_CAST obj.events[i].actions[ii].functionname);
      xmlTextWriterWriteElement(writer, BAD_CAST "codestring", BAD_CAST obj.events[i].actions[ii].codestring);
      xmlTextWriterWriteElement(writer, BAD_CAST "whoName", BAD_CAST obj.events[i].actions[ii].whoName);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "relative","%i", obj.events[i].actions[ii].relative);
      xmlTextWriterWriteFormatElement(writer, BAD_CAST "isnot","%i", obj.events[i].actions[ii].isnot);
      xmlTextWriterStartElement(writer, BAD_CAST "arguments");
      int iii;
      for (iii = 0; iii<obj.events[i].actions[ii].arg_count-1;iii++)
      {
        //causing some of these to nest rather than properly close
        xmlTextWriterStartElement(writer, BAD_CAST "argument");
        xmlTextWriterWriteFormatElement(writer, BAD_CAST "kind", "%i", obj.events[i].actions[ii].arguments[iii].kind);
        xmlTextWriterWriteElement(writer, BAD_CAST "string", obj.events[i].actions[ii].arguments[iii].string);
        xmlTextWriterEndElement(writer); //Close <argument>
      }
      xmlTextWriterEndElement(writer); //Close <arguments>
      xmlTextWriterEndElement(writer); //Close <action>
    }
    xmlTextWriterEndElement(writer); //Close <event>
  }
  xmlTextWriterEndElement(writer); //Close <events>
  //Put physics stuff here
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObject","%i", obj.PhysicsObject);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectSensor","%i", obj.PhysicsObjectSensor);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectShape","%i", obj.PhysicsObjectShape);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectDensity","%f", obj.PhysicsObjectDensity);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectRestitution","%f", obj.PhysicsObjectRestitution);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectGroup","%i", obj.PhysicsObjectGroup);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectLinearDamping","%f", obj.PhysicsObjectLinearDamping);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectAngularDamping","%f", obj.PhysicsObjectAngularDamping);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectFriction","%f", obj.PhysicsObjectFriction);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectAwake","%i", obj.PhysicsObjectAwake);
  xmlTextWriterWriteFormatElement(writer, BAD_CAST "PhysicsObjectKinematic","%i", obj.PhysicsObjectKinematic);
  xmlTextWriterStartElement(writer, BAD_CAST "PhysicsShapePoints");
  //This is where we store any floats that need to be converted to strings
  char str_float_converted[(CHAR_BIT * sizeof(float) - 1) / 3 + 2];
  for (i=0;i<obj.point_count;i++)
  {
    xmlTextWriterWriteFormatElement(writer, BAD_CAST "point","%i,%i", obj.PhysicsShapePoints[i].x, obj.PhysicsShapePoints[i].y);
  }
  xmlTextWriterEndElement(writer); //Close <PhysicsShapePoints>
  xmlTextWriterEndDocument(writer);
  xmlFreeTextWriter(writer);
}