# 帳票設計書 6-to xml

## 概要

本ドキュメントは、Nushellの`to xml`コマンドに関する設計書である。`to xml`コマンドは、特殊なレコード構造をXML (eXtensible Markup Language) 形式のテキストに変換するデータ変換コマンドである。

### 本帳票の処理概要

`to xml`コマンドは、Nushellの特定のレコード構造（tag, attributes, contentフィールドを持つ）をXML形式のテキストに変換する。単純なテーブルデータではなく、XMLの階層構造を表現するための専用データ構造を入力として受け取る。

**業務上の目的・背景**：XMLはエンタープライズシステム、SOAP Webサービス、設定ファイル、ドキュメントフォーマットなどで広く使用されている。Nushellで構築したデータ構造をXML形式で出力することで、既存のXMLベースのシステムとの連携を可能にする。

**帳票の利用シーン**：
- XML設定ファイルの生成
- SOAP APIリクエストの構築
- ドキュメント形式（XHTML等）の生成
- データエクスポート
- 他システムとのXML連携

**主要な出力内容**：
1. XMLタグ要素（tag, attributes, contentから生成）
2. XMLコメント（tag: '!'で表現）
3. 処理命令（PI、tag: '?name'で表現）
4. テキストノード

**帳票の出力タイミング**：パイプライン処理において`to xml`コマンドが実行されたとき

**帳票の利用者**：Nushellユーザー、システムインテグレーター、Webサービス開発者

## 帳票種別

データ変換出力（テキスト形式）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | Nushell CLI | コマンドライン | `to xml` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | XML (テキスト) |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | パイプラインで`save`コマンドと組み合わせて指定 |
| 出力方法 | 標準出力またはファイル保存 |
| 文字コード | UTF-8 |

### 出力オプション

| オプション | 短縮形 | 説明 | デフォルト値 |
|-----------|--------|------|-------------|
| --indent | -i | インデント幅（スペース数） | なし（インデントなし） |
| --partial-escape | -p | 必須文字のみエスケープ | false |
| --self-closed | -s | 空タグをself-closingで出力 | false |

## 帳票レイアウト

### レイアウト概要

XML出力は入力のレコード構造に基づく：

```
┌─────────────────────────────────────┐
│  XML構造                            │
│  <root attr="value">                │
│    <child>text</child>              │
│    <!-- comment -->                 │
│    <?pi content?>                   │
│  </root>                            │
└─────────────────────────────────────┘
```

### 入力レコード構造

| No | フィールド | 説明 | 必須 |
|----|-----------|------|-----|
| 1 | tag | タグ名（文字列）または特殊記号 | Yes (通常タグ) |
| 2 | attributes | 属性のレコード | No |
| 3 | content | 子要素のリストまたはテキスト | No |

### 特殊タグ構文

| タグ値 | 意味 | content | attributes |
|-------|------|---------|------------|
| 通常文字列 | XMLタグ | 子要素リスト | 属性レコード |
| '!' | コメント | コメントテキスト | null |
| '?name' | 処理命令 | PI内容テキスト | null |
| null | テキストノード | テキスト内容 | null |

## 出力条件

### 入力条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 入力データ型 | record | Yes |
| tag/attributes/content以外のカラム | エラー | - |

### 制約条件

| 条件名 | 説明 |
|-------|------|
| 文字列トップレベル | エラー（文字列はルート要素不可） |
| コメントトップレベル | エラー（コメントはルート要素不可） |
| PIトップレベル | エラー（PIはルート要素不可） |
| タグ名'!'/'?'で始まる | エラー（予約語） |

## データベース参照仕様

### 参照テーブル一覧

本コマンドはデータベースを直接参照しない。パイプラインから受け取るデータを処理する。

## 計算仕様

### 計算項目一覧

| 項目名 | 処理 | 備考 |
|-------|------|------|
| 文字エスケープ | `<>&"` をエンティティ変換 | --partial-escape時は一部のみ |
| 属性エスケープ | `<>&"` をエンティティ変換 | 属性値内 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[入力データ受信] --> B[オプション解析]
    B --> C[Job構造体作成]
    C --> D[write_xml_entry呼び出し]
    D --> E{エントリ種別判定}
    E -->|通常タグ| F[write_tag]
    E -->|コメント| G[write_comment]
    E -->|PI| H[write_processing_instruction]
    E -->|テキスト| I[write_xml_text]
    F --> J[子要素再帰処理]
    J --> K[quick_xml::Writer出力]
    G --> K
    H --> K
    I --> K
    K --> L[UTF-8文字列変換]
    L --> M[メタデータ付与]
    M --> N[PipelineData返却]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| CantConvert | 無効なカラム名 | "Invalid column ... Only tag, attributes and content are permitted" | 正しいカラム名を使用 |
| CantConvert | 文字列がルート | "Strings can not be a root element of document" | タグ要素でラップ |
| CantConvert | コメントがルート | "Comments can not be a root element of document" | タグ要素でラップ |
| CantConvert | PIがルート | "PIs can not be a root element of document" | タグ要素でラップ |
| CantConvert | タグ名が!/?で開始 | "tag name can not start with ! or ?" | 有効なタグ名を使用 |
| CantConvert | 属性値が非文字列 | "Attribute value expected to be a string" | 文字列に変換 |
| NonUtf8 | UTF-8変換失敗 | "NonUtf8" | 有効なUTF-8データを使用 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | メモリ制限内 |
| 目標出力時間 | データサイズに依存 |
| 同時出力数上限 | N/A |

## セキュリティ考慮事項

- XMLインジェクション対策として、quick_xmlクレートが適切なエスケープを行う
- --partial-escapeオプション使用時は最小限のエスケープのみ実施

## 備考

- content_type メタデータは "application/xml" として設定される
- quick_xmlクレートを使用してXML生成を実施
- 入力は`from xml`コマンドの出力形式と互換性あり

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、XML表現のためのレコード構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nu_xml_format.rs | `crates/nu-command/src/formats/nu_xml_format.rs` | COLUMN_TAG_NAME, COLUMN_ATTRS_NAME, COLUMN_CONTENT_NAMEの定義 |
| 1-2 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | Job構造体の定義（110-114行目） |

**読解のコツ**: XMLの各要素タイプ（タグ、コメント、PI、テキスト）がどのようにレコードで表現されるか確認する。

#### Step 2: エントリーポイントを理解する

`to xml`コマンドの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | ToXml構造体とCommandトレイト実装（12-108行目） |

**主要処理フロー**:
1. **19-39行目**: シグネチャ定義（--indent, --partial-escape, --self-closedオプション）
2. **41-50行目**: extra_descriptionでXML構文説明
3. **92-107行目**: runメソッドでオプション解析とJob実行

#### Step 3: XML生成ロジックを理解する

各要素タイプの生成ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | Job::run関数（130-146行目） |
| 3-2 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | write_xml_entry関数（193-266行目） |
| 3-3 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | write_tag関数（416-470行目） |
| 3-4 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | write_comment関数（356-383行目） |
| 3-5 | xml.rs | `crates/nu-command/src/formats/to/xml.rs` | write_processing_instruction関数（385-414行目） |

**主要処理フロー**:
- **193-204行目**: 文字列の直接テキスト出力判定
- **206-217行目**: レコードの検証（有効なカラムのみ）
- **235-257行目**: tag値による分岐（コメント/PI/タグ）
- **416-470行目**: タグ要素の出力（属性、子要素含む）

### プログラム呼び出し階層図

```
ToXml::run (xml.rs:92)
    │
    └─ Job::new (xml.rs:117)
           │
           └─ Job::run (xml.rs:130)
                  │
                  └─ write_xml_entry (xml.rs:193)
                         │
                         ├─ write_xml_text (xml.rs:489) [テキスト]
                         │
                         └─ write_tag_like (xml.rs:276)
                                │
                                ├─ write_comment (xml.rs:356) [tag='!']
                                │
                                ├─ write_processing_instruction (xml.rs:385) [tag='?...']
                                │
                                └─ write_tag (xml.rs:416) [通常タグ]
                                       │
                                       ├─ add_attributes (xml.rs:148)
                                       │
                                       └─ write_xml_entry (再帰) [子要素]
```

### データフロー図

```
[入力]                      [処理]                           [出力]

Record                  ──▶ ToXml::run ──────────────────▶ PipelineData::Value
{tag, attrs, content}        │                              │
                             ▼                              ▼
                        Job::run                       XML形式文字列
                             │                         "<tag>...</tag>"
                             ▼
                        write_xml_entry
                        (エントリ種別判定)
                             │
                             ▼
                        quick_xml::Writer
                        (XMLイベント出力)
                             │
                             ▼
                        UTF-8文字列変換
                             │
                             ▼
                        metadata付与
                        (application/xml)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| xml.rs | `crates/nu-command/src/formats/to/xml.rs` | ソース | to xmlコマンドの実装 |
| nu_xml_format.rs | `crates/nu-command/src/formats/nu_xml_format.rs` | ソース | XMLフォーマット共通定義 |
| mod.rs | `crates/nu-command/src/formats/to/mod.rs` | ソース | toモジュールの公開定義 |
| quick_xml (crate) | 外部依存 | ライブラリ | XML出力ライブラリ |
