Files
dataxl/docs/architecture.md
Luno 2e96d174f2
All checks were successful
CI / test (pull_request) Successful in 26s
Document conversion internals and limits
2026-07-18 16:25:50 +09:00

3.6 KiB

Architecture

dataxl は、ファイル形式ごとの差を小さくするために、内部表現を2つに分けています。

  • structured value: JSON/YAML/TOMLから読める map[string]any, []any, scalar
  • table: Excel/CSV/TSVに近い Header []stringRows [][]string

変換は原則として次のどれかです。

  • structured -> structured
  • structured -> table
  • table -> structured
  • table -> table

Source Layout

実装は cmd/dataxl package内で責務別に分割しています。

  • main.go: CLI option、stdin/stdout、ファイル入出力
  • conversion.go: 変換経路の選択、形式名の正規化・推定
  • structured.go: JSON/YAML/TOML adapter
  • table.go: CSV/TSV/XLSX adapter、table model、flatten
  • path.go: セル値の型推定、列パスのparse、unflatten

convert はファイル入出力から独立しているため、CLIを経由せず変換matrixをテストできます。 形式固有処理は parseStructured / encodeStructured または parseTable / encodeTable に閉じ込めます。

現状は単一commandだけが利用するため同じpackageに置いています。別commandやlibrary APIから 再利用する段階になったら、安定させたい境界を見極めたうえで internal packageへ移します。

Table Model

表形式は必ず1行目をヘッダーとして扱います。

type table struct {
    Header []string
    Rows   [][]string
}

CSV/TSV/XLSXの読み込みでは、短い行を空文字で埋めて列数を揃えます。 XLSXの書き出しではヘッダーを太字にし、1行目を固定します。

Flattening

structured -> table では、入れ子のmap/arrayを列パスへ展開します。

  • map: user.name
  • array: items[0].sku
  • top-level scalar: value

列順は安定性を優先してソートしています。Excel上で列の位置が変わっても、 ヘッダー名を見て復元するため、列順には依存しません。

Unflattening

table -> structured では、ヘッダーのパス表現からmap/arrayを復元します。

例:

items[0].sku

は次の構造になります。

{
  "items": [
    {
      "sku": "..."
    }
  ]
}

セル値は parseCell で軽く型推定します。

  • 空文字: ""
  • true / false: boolean
  • 整数: int64
  • 小数または指数表記: float64
  • その他: string

ゼロ埋め整数は、IDやコードを壊さないためstringとして保持します。複数列が同じパスで 異なる中間型を要求する場合は、先に構築された値を後続列で上書きしません。

Path grammar

現在の列パスは次の要素を扱います。

path  = key, { ".", key | "[", index, "]" };
index = digit, { digit };

実例は user.nameitems[0].skuorders[0].items[1].qty です。 区切り文字を含むmap keyのescapeは未対応です。

TOML Output

TOMLはトップレベル配列を直接表せないため、表からTOMLへ出力する場合など、 トップレベルがmapでない値は rows キーに包んで出力します。

Dependencies

  • github.com/xuri/excelize/v2: XLSX読み書き
  • gopkg.in/yaml.v3: YAML読み書き
  • github.com/BurntSushi/toml: TOML読み書き

Go 1.24以上を前提にしています。

Error handling

  • 未対応形式、decode失敗、workbook/sheet操作失敗は呼び出し元へerrorを返します。
  • path復元中の型競合は既存値を保護するため、その列の適用を中止します。
  • XLSXのstyle・pane設定も通常の変換errorとして扱い、不完全なworkbookを成功扱いしません。