2

Cプログラムでminixmlを使って遊んでいます。そして、minixmlツリーをmxmlSaveFile(bkp_tree, fp, MXML_NO_CALLBACK);関数を使用してファイルに保存すると、xmlデータ全体が1つのブロックにまとめられます。ファイル内のxml構造を表示するための編成はありません(改行、インデント...)。

xmlデータはこの方法で保存されます

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

次の方法でXMLデータを保存するminixmlを作成するにはどうすればよいですか?

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

2 に答える 2

2

minixmlドキュメントからコピー:

コールバック関数は、ノードへのポインタと、、、、、またはの「where」値MXML_WS_BEFORE_OPENを使用してMXML_WS_AFTER_OPEN、要素ノードごとに最大4回呼び出されます。空白を追加しない場合はコールバック関数を返し、それ以外の場合は挿入する文字列(スペース、タブ、キャリッジリターン、改行)を返す必要があります。MXML_WS_BEFORE_CLOSEMXML_WS_AFTER_CLOSENULL

次の空白のコールバックを使用して、XHTML出力に空白を追加し、標準のテキストエディタで読みやすくすることができます。

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);
}

このコールバック関数を使用するには、保存関数のいずれかを呼び出すときに名前を使用するだけです。

FILE *fp;
mxml_node_t *tree;

fp = fopen("filename.xml", "w");
mxmlSaveFile(tree, fp, whitespace_cb);
fclose(fp);
于 2013-01-23T15:13:28.863 に答える
2

を与える代わりにMXML_NO_CALLBACK、各要素の前後に印刷する必要のある空白を返すコールバックを与えることができます。のドキュメントを参照してくださいmxmlSaveFile

コールバックが基本的に受け取るのは、の4つの可能な値の1つに追加の引数を付けて出力されようとしている各ノードです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;
    }
}
于 2013-01-23T13:56:30.417 に答える