# 機能設計書 30-System.Xml.XmlSerializer

## 概要

本ドキュメントは、.NETランタイムのSystem.Xml.Serialization名前空間が提供するXMLシリアライズ機能について、その設計仕様と実装の詳細を記述する。オブジェクトとXML間の変換を行う機能を提供する。

### 本機能の処理概要

System.Xml.Serializationは、.NETオブジェクトをXML形式にシリアライズし、XMLから.NETオブジェクトにデシリアライズするためのライブラリである。XmlSerializerクラスを中心に、属性による細かなマッピング制御、スキーマ生成、カスタムシリアライズをサポートする。

**業務上の目的・背景**：XMLはWebサービス（SOAP/WCF）、設定ファイル、データ交換フォーマットとして広く使用される。XmlSerializerは、オブジェクトとXMLの間の変換を自動化し、開発効率を向上させる。

**機能の利用シーン**：
- SOAPベースWebサービスの通信
- 設定ファイルの永続化・読み込み
- XMLベースのデータ交換
- XMLスキーマに準拠したXML生成
- オブジェクトのXML形式でのログ出力
- レガシーシステムとのXML連携

**主要な処理内容**：
1. オブジェクトのXMLへのシリアライズ（Serialize）
2. XMLからオブジェクトへのデシリアライズ（Deserialize）
3. 属性によるマッピングカスタマイズ
4. XMLスキーマの生成・読み込み
5. 不明な要素/属性のイベント処理
6. 事前生成シリアライザのサポート

**関連システム・外部連携**：XmlReader/XmlWriter、XmlSchema、WCF/ASMX Webサービス。

**権限による制御**：動的コード生成を使用する場合、適切な権限が必要（AOT環境では制限あり）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はUIを持たないライブラリ機能である |

## 機能種別

XMLシリアライズ / オブジェクトマッピング / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| type | Type | Yes | シリアライズ対象の型 | null不可 |
| o | object | No | シリアライズ対象オブジェクト | 指定型のインスタンス |
| stream | Stream | Yes (Deserialize) | XMLを含むストリーム | 読み取り可能 |
| xmlReader | XmlReader | No | XMLリーダー | null可 |
| overrides | XmlAttributeOverrides | No | 属性オーバーライド | null可 |
| extraTypes | Type[] | No | 追加の型情報 | null可 |
| root | XmlRootAttribute | No | ルート要素設定 | null可 |

### 入力データソース

- .NETオブジェクト（シリアライズ時）
- XMLストリーム/リーダー（デシリアライズ時）
- 型メタデータ（リフレクション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| XML | string/Stream | シリアライズされたXML |
| object | object | デシリアライズされたオブジェクト |

### 出力先

- Stream/TextWriter（シリアライズ時）
- XmlWriter
- オブジェクトインスタンス（デシリアライズ時）

## 処理フロー

### 処理シーケンス

```
1. XmlSerializer作成
   └─ new XmlSerializer(typeof(MyClass))
   └─ リフレクションによる型分析
   └─ シリアライザコード生成（または事前生成）

2. シリアライズ
   └─ serializer.Serialize(stream, obj)
   └─ XmlWriter経由でXML出力
   └─ 属性に基づくマッピング

3. デシリアライズ
   └─ serializer.Deserialize(stream)
   └─ XmlReader経由でXML読み取り
   └─ オブジェクトインスタンス生成
   └─ プロパティ/フィールド設定

4. イベント処理
   └─ UnknownNode/UnknownAttribute/UnknownElement
   └─ イベントハンドラで処理
```

### フローチャート

```mermaid
flowchart TD
    A[XmlSerializer生成] --> B{モード判定}
    B -->|動的生成| C[TempAssembly生成]
    B -->|リフレクション| D[ReflectionXmlSerializer]
    B -->|事前生成| E[LoadGeneratedAssembly]
    C --> F[シリアライザ準備完了]
    D --> F
    E --> F
    F --> G{操作}
    G -->|Serialize| H[オブジェクト走査]
    G -->|Deserialize| I[XML読み取り]
    H --> J[XmlWriter出力]
    I --> K[オブジェクト構築]
    J --> L[XML完成]
    K --> M[オブジェクト完成]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パブリックメンバー | シリアライズ対象はpublicプロパティ/フィールド | 常時 |
| BR-02 | 既定コンストラクタ | デシリアライズにはパラメータなしコンストラクタが必要 | デシリアライズ時 |
| BR-03 | 属性マッピング | XmlElementAttribute等で要素名をカスタマイズ可能 | 属性付与時 |
| BR-04 | キャッシュ | 同一型のXmlSerializerはキャッシュして再利用推奨 | パフォーマンス最適化 |

### 計算ロジック

シリアライザモード判定:
- RuntimeFeature.IsDynamicCodeSupported → 動的生成
- それ以外 → リフレクションベース
- 事前生成アセンブリ検出 → 事前生成使用

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidOperationException | 例外 | シリアライズ/デシリアライズエラー | XMLと型の整合性を確認 |
| ArgumentNullException | 例外 | typeがnull | 有効な型を指定 |
| XmlException | 例外 | 不正なXML形式 | 整形式XMLを使用 |
| FileLoadException | 例外 | PreGenモードで事前生成アセンブリがない | アセンブリを生成 |

### リトライ仕様

シリアライズ/デシリアライズエラーは通常、データの修正が必要でリトライでは解決しない。

## トランザクション仕様

本機能はトランザクションを使用しない。

## パフォーマンス要件

- XmlSerializerインスタンスはスレッドセーフ
- 同一型のXmlSerializerは再利用推奨（キャッシュ使用）
- 初回生成時にコード生成のオーバーヘッドあり
- 大量のプロパティを持つ型は処理時間増加

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

- 外部XMLのデシリアライズは信頼性を確認
- DTD処理に注意（XXE攻撃対策）
- 動的コード生成には適切な権限が必要
- RequiresUnreferencedCode/RequiresDynamicCode属性による警告

## 備考

- AOT環境ではリフレクションベースまたは事前生成が必要
- sgen.exeで事前生成可能
- .NET 6以降でソースジェネレータ対応検討

---

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

### 推奨読解順序

#### Step 1: XmlSerializerクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | XmlSerializer.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs` | メインクラス |

**主要処理フロー（XmlSerializer.cs）**:
- **112行目**: XmlSerializerクラス定義
- **114行目**: s_modeフィールド（SerializationMode）
- **116-120行目**: Modeプロパティ（動的/リフレクション判定）
- **130-139行目**: 内部フィールド（_tempAssembly、_primitiveType、_mapping等）
- **141行目**: s_cacheフィールド（TempAssemblyCache）
- **161-163行目**: Trim警告メッセージ定数
- **166-168行目**: protectedデフォルトコンストラクタ
- **208-212行目**: XmlSerializer(Type)コンストラクタ
- **216-272行目**: XmlSerializer(Type, string)コンストラクタ（メイン初期化ロジック）
- **332-337行目**: Serialize(TextWriter, object)メソッド
- **369-419行目**: Serialize(XmlWriter, object, namespaces, encodingStyle, id)メソッド（コア実装）
- **442-448行目**: Deserialize(Stream)メソッド
- **484-526行目**: Deserialize(XmlReader, encodingStyle, events)メソッド（コア実装）
- **543-566行目**: CanDeserialize(XmlReader)メソッド
- **779-825行目**: UnknownNode/UnknownAttribute/UnknownElement/UnreferencedObjectイベント

#### Step 2: シリアライズ/デシリアライズ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ReflectionXmlSerializationWriter.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationWriter.cs` | リフレクションベースの書き込み |
| 2-2 | ReflectionXmlSerializationReader.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs` | リフレクションベースの読み取り |
| 2-3 | XmlSerializationWriter.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs` | 書き込み基底クラス |
| 2-4 | XmlSerializationReader.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs` | 読み取り基底クラス |

#### Step 3: 属性を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | XmlElementAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlElementAttribute.cs` | 要素属性 |
| 3-2 | XmlAttributeAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeAttribute.cs` | 属性属性 |
| 3-3 | XmlRootAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlRootAttribute.cs` | ルート要素属性 |
| 3-4 | XmlIgnoreAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlIgnoreAttribute.cs` | 除外属性 |
| 3-5 | XmlTypeAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeAttribute.cs` | 型属性 |

#### Step 4: サポートクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | XmlReflectionImporter.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs` | 型からマッピング生成 |
| 4-2 | XmlTypeMapping.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeMapping.cs` | 型マッピング |
| 4-3 | XmlSerializerFactory.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializerFactory.cs` | シリアライザファクトリ |

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

```
new XmlSerializer(Type)
├── GetKnownMapping() - プリミティブ型チェック
├── s_cache[type] - キャッシュ確認
└── (キャッシュなし時)
    ├── TempAssembly.LoadGeneratedAssembly() - 事前生成確認
    │   └── 見つかれば TempAssembly作成
    └── (事前生成なし時)
        ├── XmlReflectionImporter.ImportTypeMapping()
        │   └── 型分析・マッピング生成
        └── GenerateTempAssembly()
            └── TempAssembly生成

XmlSerializer.Serialize(XmlWriter, object)
├── (_primitiveType != null)
│   └── SerializePrimitive() - プリミティブ直接書き込み
├── (ShouldUseReflectionBasedSerialization)
│   └── SerializeUsingReflection()
│       └── ReflectionXmlSerializationWriter.WriteObject()
└── (_tempAssembly != null)
    └── _tempAssembly.InvokeWriter()

XmlSerializer.Deserialize(XmlReader)
├── (_primitiveType != null)
│   └── DeserializePrimitive() - プリミティブ直接読み取り
├── (ShouldUseReflectionBasedSerialization)
│   └── DeserializeUsingReflection()
│       └── ReflectionXmlSerializationReader.ReadObject()
└── (_tempAssembly != null)
    └── _tempAssembly.InvokeReader()
```

### データフロー図

```
[.NETオブジェクト]
     │
     ▼
┌────────────────────┐
│    XmlSerializer   │
│  ┌──────────────┐  │
│  │ _mapping     │  │ ← XmlTypeMapping（型-XML対応）
│  │ _tempAssembly│  │ ← TempAssembly（生成コード）
│  │ _primitiveType│ │ ← プリミティブ型キャッシュ
│  └──────────────┘  │
└────────────────────┘
     │
     ├── Serialize ──────────────────┐
     │                               ▼
     │               ┌──────────────────────────┐
     │               │ XmlSerializationWriter   │
     │               │ (Reflection/Generated)   │
     │               └──────────────────────────┘
     │                               │
     │                               ▼
     │                         [XmlWriter]
     │                               │
     │                               ▼
     │                         [XMLストリーム]
     │
     └── Deserialize ─────────────────┐
                                      ▼
                      ┌──────────────────────────┐
                      │ XmlSerializationReader   │
                      │ (Reflection/Generated)   │
                      └──────────────────────────┘
                                      │
                                      ▼
                                [XmlReader]
                                      │
                                      ▼
                              [.NETオブジェクト]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| XmlSerializer.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializer.cs` | ソース | メインシリアライザ |
| XmlSerializationWriter.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationWriter.cs` | ソース | 書き込み基底 |
| XmlSerializationReader.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializationReader.cs` | ソース | 読み取り基底 |
| ReflectionXmlSerializationWriter.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationWriter.cs` | ソース | リフレクション書き込み |
| ReflectionXmlSerializationReader.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs` | ソース | リフレクション読み取り |
| XmlReflectionImporter.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlReflectionImporter.cs` | ソース | リフレクションインポート |
| XmlTypeMapping.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeMapping.cs` | ソース | 型マッピング |
| XmlMapping.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlMapping.cs` | ソース | マッピング基底 |
| XmlElementAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlElementAttribute.cs` | ソース | 要素属性 |
| XmlAttributeAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeAttribute.cs` | ソース | 属性属性 |
| XmlRootAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlRootAttribute.cs` | ソース | ルート属性 |
| XmlIgnoreAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlIgnoreAttribute.cs` | ソース | 除外属性 |
| XmlTypeAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTypeAttribute.cs` | ソース | 型属性 |
| XmlArrayAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayAttribute.cs` | ソース | 配列属性 |
| XmlArrayItemAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlArrayItemAttribute.cs` | ソース | 配列項目属性 |
| XmlTextAttribute.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlTextAttribute.cs` | ソース | テキスト属性 |
| XmlAttributeOverrides.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributeOverrides.cs` | ソース | 属性オーバーライド |
| XmlAttributes.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlAttributes.cs` | ソース | 属性コレクション |
| XmlSerializerNamespaces.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializerNamespaces.cs` | ソース | 名前空間設定 |
| XmlSerializerFactory.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/XmlSerializerFactory.cs` | ソース | ファクトリ |
| Compilation.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/Compilation.cs` | ソース | 動的コンパイル |
| IXmlSerializable.cs | `src/libraries/System.Private.Xml/src/System/Xml/Serialization/IXmlSerializable.cs` | ソース | カスタムシリアライズIF |
