F# から XML へのコンバーター
F# の record や値を貼り付けると、きれいな XML が返ります。
このツールでできること
F# を書いていて、.NET の XML 設定ファイル、WCF コントラクト、あるいは SOAP エンドポイントの近くで作業しているなら、この痛みはよく分かるはずです — record 型はきれいで表現力豊かなのに、それに合わせた XML を手書きするのは苦行です。ここに F# を貼り付ければ、整形式の XML が一度で返ってきます — 単一の record、値を入れた let バインディング、あるいはネストした record を含むモジュール全体でも。
このコンバーターは、実際に気になる F# の癖を把握しています。Some "x" を保持する option<string> は通常の要素になります。None は消えてしまうのではなく空要素になるので、XML の形は予測可能なままです。decimal リテラル(249.99m)はサフィックスが落ちます。list、seq、配列はコンテナ要素になり、各項目が 1 つずつ子要素として入ります — .NET で round-trip したときに System.Xml.Serialization が内部的に出力するのと同じです。
判別共用体も素直に扱われます — ケース名が要素タグになり、ペイロードは子要素になります。ネストした record はインラインで展開され、tuple のフィールドは兄弟要素として出力され、Map<K,V> は <Entry><Key/><Value/></Entry> のペアになります。属性でのカスタマイズ([<XmlElement>]、[<XmlAttribute>])については、F# の .NET 相互運用に関するドキュメント を参照してください — コンバーターは存在する場合それらを尊重します。
使い方
3 ステップです。1 行の record でもモジュール全体でも同じ流れです。
F# を貼り付ける(またはサンプルを試す)
左のエディタに F# をそのまま貼り付けます。record 型、値を入れた let バインディング、複数の record、あるいは 判別共用体 — どれでも OK です。まずはリアルな例を見たいときは サンプルを読み込む をクリックしてください。
open 文を削ったり、F# のシンタックス を整える必要はありません。Rider や VS Code に表示されているままのコードで大丈夫です。そのまま貼ってください。
変換をクリック
緑色の 変換 ボタンをクリックします。ツールが record をパースし、値の入ったインスタンスをたどって、一度で XML を生成します。実行中は短いローディングインジケーターが表示されます。
XML をコピー
右側のパネルにインデント済みで整形式の XML が入り、どの標準準拠パーサーでも受け付けられます。app.config、SOAP フィクスチャ、XmlSerializer の round-trip テスト、あるいはドキュメントにそのまま貼り付けてください。
実際に役立つ場面
.NET XML 設定ファイル
app.config / web.config のセクションをモデリングした F# の record が、編集可能な XML テンプレートに変わります — 手で angle bracket を書く必要はありません。
WCF と SOAP のフィクスチャ
WCF のデータコントラクトをミラーした F# record がある。貼り付けて SOAP 形式のボディを取得し、SoapUI か Postman に流し込む。
レガシー XML エンドポイントとの Fable 連携
Fable で古い XML API と通信していますか?共有の F# record を貼り付ければ、バックエンドが期待する XML ボディを取得できます。option フィールドも正しく処理されます。
XmlSerializer 用のテストデータ
<code>XmlSerializer<T></code> を通しても驚きなく round-trip する XML のシードデータを生成できます — 統合テスト、モックサーバー、リグレッションスイートに役立ちます。
よくある質問
複数の record を一度に貼り付けられますか?
はい — モジュール全体を貼り付けて OK です。それぞれの record 型はネストされた record が展開された状態で処理され、and でチェーンされた型定義もきちんと扱われます。判別共用体のケースはケース名を要素タグとして保持します。
option、None、デフォルト値はどう扱われますか?
Some "x" を持つ option<string> はテキストを含む通常の要素になります。None は空要素になるので形が安定します — 値が入った record と入っていない record の間でフィールドが消えることはありません。voption も同じ振る舞いです。
decimal、DateTime、Guid、その他の厄介な型は?
decimal(249.99m)はサフィックスが落ちて普通の数値テキストになります。DateTime、DateTimeOffset、TimeSpan は ISO-8601 文字列になります。Guid は標準的な 8-4-4-4-12 の 16 進形式のままです。byte[] は base64 テキストになります — XmlSerializer の動作と一致します。
判別共用体は動きますか?
はい。type Status = Active | Suspended of reason: string のような DU は、引数なしのケースでは <Active/> を、ペイロード付きのケースでは <Suspended><reason>...</reason></Suspended> を出力します。ケース名が要素タグになります — スキーマに合わせた XML では通常これが望ましい形です。
貼り付けたコードは保存されますか?
コードは変換のためにバックエンドへ送られますが保存しません — ペイロードはログにも残しません。F# が機密性の高いもの(社内コントラクト、リテラルに含まれる API キーなど)の場合は、貼り付ける前に確認してください。
F# でコンピュテーション式やアクティブパターンを使っている場合は?
それらは XML のフィールドを生成しません — 制御フローの構文であってデータではないからです。ツールは record 型の定義と値が入ったインスタンスを見ているので、async { ... } や banana-clip パターンマッチは無視されます。まず明らかな構文エラーを直して、パーサーが噛み切れる状態にしてください。
一緒に使えるツール
F# から XML はパズルの一ピースです。これらと相性が良いです: