如何使mini xml数据的呈现更具可读性?

时间:2013-01-23 13:50:10

标签: c++ c xml mini-xml

我在我的C程序中使用minixml。当我将minixml树保存到具有mxmlSaveFile(bkp_tree, fp, MXML_NO_CALLBACK);函数的文件中时,我将整个xml数据保存在一个块中。没有组织在文件中显示xml结构(新行,缩进...)。

xml数据以这种方式保存

<B1><BB1>BBB1</BB1></B1><B2><BB2>BBB2</BB2></B2><B3><BB3>BBB3</BB3></B3>

如何使minixml以下列方式保存xml数据?

<B1>
    <BB1>BBB1</BB1>
</B1>
<B2>
    <BB2>BBB2</BB2>
</B2>
<B3>
    <BB3>BBB3</BB3>
</B3>

2 个答案:

答案 0 :(得分:2)

不是给MXML_NO_CALLBACK,而是给出一个回调,它返回在每个元素之前和之后应该打印的空格。请参阅mxmlSaveFile的文档。

回调基本上接收的是每个节点,即将在MXML_WS_BEFORE/AFTER_OPEN/CLOSE的四个可能值之一中使用附加参数进行打印。在这两种情况中,您应该决定如何在此打开或关闭节点之前或之后的空格。

(我希望)输出您想要的内容如下:

static const char *_xml_whitespace_callback(mxml_node_t *node, int where)
{
    const char *name = node->value.element.name;

    if (node->type != MXML_ELEMENT)
        return NULL;
    if (name == NULL)
        return NULL;

    switch (where)
    {
    case MXML_WS_BEFORE_OPEN:
        if (strcmp(name, "B1") == 0
                || strcmp(name, "B2") == 0)
                || strcmp(name, "B3") == 0))
            return NULL;
        if (strcmp(name, "BB1") == 0
                || strcmp(name, "BB2") == 0)
                || strcmp(name, "BB3") == 0))
            return "\t";
        return NULL;
    case MXML_WS_AFTER_OPEN:
        if (strcmp(name, "B1") == 0
                || strcmp(name, "B2") == 0)
                || strcmp(name, "B3") == 0))
            return "\n";
        if (strcmp(name, "BB1") == 0
                || strcmp(name, "BB2") == 0)
                || strcmp(name, "BB3") == 0))
            return NULL;
        return NULL;
    case MXML_WS_BEFORE_CLOSE:
        return NULL;
    case MXML_WS_AFTER_CLOSE:
        return "\n";
    default:
        return NULL;
    }
}

答案 1 :(得分:2)

minixml documentation复制:

对于每个元素节点,您的回调函数最多会调用四次,其指针指向节点,“where”值为MXML_WS_BEFORE_OPENMXML_WS_AFTER_OPENMXML_WS_BEFORE_CLOSE或{ {1}}。如果不应添加空格,则回调函数应返回MXML_WS_AFTER_CLOSE,否则将返回要插入的字符串(空格,制表符,回车符和换行符)。

以下空格回调可用于向XHTML输出添加空格,以使其在标准文本编辑器中更具可读性:

NULL

要使用此回调函数,只需在调用任何保存函数时使用该名称:

const char *
whitespace_cb(mxml_node_t *node,
              int where)
{
  const char *name;

 /*
  * We can conditionally break to a new line
  * before or after any element. These are
  * just common HTML elements...
  */

  name = mxmlGetElement(node);

  if (!strcmp(name, "html") ||
      !strcmp(name, "head") ||
      !strcmp(name, "body") ||
  !strcmp(name, "pre") ||
      !strcmp(name, "p") ||
  !strcmp(name, "h1") ||
      !strcmp(name, "h2") ||
      !strcmp(name, "h3") ||
  !strcmp(name, "h4") ||
      !strcmp(name, "h5") ||
      !strcmp(name, "h6"))
  {
   /*
* Newlines before open and after
    * close...
*/

if (where == MXML_WS_BEFORE_OPEN ||
        where == MXML_WS_AFTER_CLOSE)
  return ("\n");
  }
  else if (!strcmp(name, "dl") ||
           !strcmp(name, "ol") ||
           !strcmp(name, "ul"))
  {
   /*
* Put a newline before and after list
    * elements...
*/

return ("\n");
  }
  else if (!strcmp(name, "dd") ||
           !strcmp(name, "dt") ||
           !strcmp(name, "li"))
  {
   /*
* Put a tab before <li>'s, * <dd>'s,
    * and <dt>'s, and a newline after them...
*/

if (where == MXML_WS_BEFORE_OPEN)
  return ("\t");
else if (where == MXML_WS_AFTER_CLOSE)
  return ("\n");
  }

 /*
  * Return NULL for no added whitespace...
  */

  return (NULL);
}