C to XML コンバーター
C の struct や typedef を貼れば、きれいな XML が返ります。
このツールがやること
C には組み込みの XML シリアライザーがありません。typedef struct をそのまま映した XML ドキュメントが欲しくなったら、libxml2 や Expat に頼るか、文字単位で手書きするのが普通です。ここに C を貼ればその最初の手打ち作業をスキップできて、定義したフィールド・ネスト型・配列にそろった well-formed な XML が出てきます。
おもちゃ用のサブセットではなく本物の C を読みます。typedef struct { char orderId[16]; double totalAmount; OrderItem items[2]; } Order; と C99/C11 の指定初期化子(Order o = { .orderId = "ORD-4821", ... };)を合わせると、各メンバーが子要素になった完全な <Order>...</Order> ツリーになります。固定長の char 配列は(バイト配列ではなく)文字列として扱い、数値型はそのリテラル形を保ち、<stdbool.h> の bool は出力で true / false になります。
配列とネストした struct は、手書きしたときと同じ形で出てきます。OrderItem items[2] は <items><OrderItem/><OrderItem/></items> になり、各要素が展開されます。ネストした typedef は実体のレイアウトまで解決されるので、double のエイリアスである MoneyAmount でも宙ぶらりんの参照ではなく数値として出ます。初期化子のないポインターは黙って落とされずに空要素になります — 古い XML 利用者にまだ XML を返している GCC ビルドのサービスで、出力をスキーマテンプレートとして使いたいときに便利です。
使い方
ステップは3つ。typedef ひとつでも、ヘッダー丸ごと + 初期化子でも動きます。
C を貼る(またはサンプルを試す)
左のエディタに C を放り込んでください — typedef struct、素の struct、指定初期化子、あるいはその組み合わせ。#include、コメント、#define マクロはそのままで大丈夫。残しておいて構いません。
きれいな例が見たい場合は サンプル読込 をクリック。OrderItem と Address をネストした現実的な Order typedef が、C99 指定初期化子の構文で初期化されて入っています。
変換を押す
緑の 変換 ボタンを押すと、struct をなめて typedef を解決し、ネスト型と配列を展開して、XML を一気に書き出します。作業中は短いローディング表示が出ます。
XML をコピー
右のパネルに well-formed でインデント済みの XML が埋まります。libxml2 のテストフィクスチャ、ファームが起動時に読む設定ファイル、Expat のコールバックテスト、ドキュメント — どこにでも貼れます。
実際に助かる場面
組み込み/ファーム用の設定テンプレート
ブートローダーや産業機器は、flash や SD から XML 設定を読むことがよくあります。設定を表す C struct を貼れば、レイアウトにバイト単位で合った編集可能な XML テンプレートが手に入ります。
libxml2 / Expat のテストフィクスチャ
パーサーのテストごとに XML サンプルを手書きするのは疲れます。パーサーが hydrate する本物の typedef から生成すれば、フィクスチャと型がずれません。
レガシー XML システムとやりとり
通信・防衛・ヘルスケアの C サービスは、パートナーと XML をやりとりする現場がまだあります。新しい struct をネットワークに流すとき、シリアライザーを書く前に正確な形を見せてくれます。
ドキュメントとスキーマ例
README や API リファレンスの「典型的なメッセージ」欄は、実際のヘッダーから例を生成するとメンテが楽です。コードが読むものとドキュメントが謳うものがずれません。
よくある質問
typedef が複数あるヘッダー全体を貼ってもいい?
はい。ヘッダー全体を貼ってください — それぞれの typedef struct を拾い、ネスト型は inline で展開し、前方宣言された型もあとで定義が出てきた時点で解決します。レイアウトの扱いでは #include、#define、コメントは無視します。
C99 / C11 の指定初期化子は理解する?
はい。Order o = { .orderId = "ORD-4821", .items = { ... } }; はフィールド名でパースするので、XML 要素名は書いたとおりになります。同じ貼り付け内に struct 定義がある場合は位置指定の集合初期化子も動きます — 宣言順にメンバーと位置を合わせます。C11 規格 6.7.9 節を参照。
char 配列・enum・union はどう扱う?
固定長の char 配列は(ほぼすべての実コードベースの慣習どおり)文字列として出力し、整数の並びにはしません。enum 値は数値ではなく列挙子名で出すので読みやすくなります。union のメンバーは、指定初期化子で最後に代入されたバリアントが明確ならそのバリアントを出し、アクティブなバリアントがあいまいな場合はコメント付きの空要素にします。
libxml2 や Expat を直接使えば済むのでは?
それらのライブラリはランタイムのシリアライズでは堅牢ですが、最初のフィクスチャや最初の設定テンプレートを手書きするのはやはり時間がかかります。そこをこのツールが削ります。XML の形が固まったら、本番経路は libxml2 や Expat に任せてください。
貼ったコードは保存される?
変換のためにバックエンドには送りますが保存はしません — ペイロードをログにも残しません。いつもどおり、ソースが機微(独自プロトコル、安全系のファーム等)なら貼る前に目を通してください。
ポインター、関数ポインター、不透明型が入っていたら?
初期化子のあるオブジェクトポインターはその参照先までたどります。未初期化のポインター、関数ポインター、不透明型(定義が見えない struct Foo*)は、変換全体を失敗させずに空要素として出力します。シリアライズ対象ではないポインター先を含む struct を XML に手書きするときの書き方と同じです。
一緒に使えるツール
C to XML はパズルの1ピースです。こちらと相性がいいです: