我在我的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>
答案 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)
对于每个元素节点,您的回调函数最多会调用四次,其指针指向节点,“where”值为MXML_WS_BEFORE_OPEN
,MXML_WS_AFTER_OPEN
,MXML_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);
}