# 機能設計書 29-System.Xml.XDocument

## 概要

本ドキュメントは、.NETランタイムのSystem.Xml.Linq名前空間が提供するXML処理（LINQ to XML）機能について、その設計仕様と実装の詳細を記述する。XMLドキュメントの作成、解析、操作を行う機能を提供する。

### 本機能の処理概要

System.Xml.Linq（LINQ to XML）は、XMLデータをメモリ上でツリー構造として表現し、LINQクエリで操作するためのライブラリである。XDocument、XElement、XAttributeなどのクラスにより、XMLの読み込み、作成、変更、保存を直感的に行える。

**業務上の目的・背景**：XMLは設定ファイル、データ交換フォーマット、Webサービス（SOAP）などで広く使用される。LINQ to XMLは、従来のDOM（XmlDocument）よりも軽量で、LINQの機能を活かした効率的なXML処理を実現する。

**機能の利用シーン**：
- 設定ファイル（app.config等）の読み書き
- RSSフィード、Atomフィードの処理
- XMLベースのデータ交換
- XHTMLドキュメントの生成・処理
- XMLシリアライズされたデータの操作
- XPath/XQuery相当のデータ抽出

**主要な処理内容**：
1. XMLの読み込み・解析（Load、Parse）
2. XMLドキュメント/要素の作成（コンストラクタ、関数型構築）
3. 要素・属性の追加・削除・更新（Add、Remove、SetValue）
4. 子孫・先祖の検索（Descendants、Ancestors）
5. LINQクエリによるフィルタリング・変換
6. XMLの保存・出力（Save、WriteTo）

**関連システム・外部連携**：XmlReader/XmlWriter、XPath、XSLT、XmlSchema等と統合可能。

**権限による制御**：特別な権限制御は不要。ファイルアクセスにはファイルシステム権限が必要。

## 関連画面

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

## 機能種別

XML処理 / LINQ to XML / データ構造

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes (Loadの場合) | XMLファイルのURI | 有効なURI形式 |
| text | string | Yes (Parseの場合) | XML文字列 | 整形式XML |
| stream | Stream | Yes (Loadの場合) | XMLを含むストリーム | 読み取り可能 |
| options | LoadOptions | No | 読み込みオプション | 有効な列挙値 |
| name | XName | Yes (要素作成) | 要素/属性名 | null不可 |
| content | object | No | 要素内容 | 様々な型を受け入れ |

### 入力データソース

- XMLファイル（URI指定）
- XML文字列
- Stream/TextReader
- XmlReader

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| XDocument | XDocument | XMLドキュメント全体 |
| XElement | XElement | XML要素 |
| XAttribute | XAttribute | XML属性 |
| IEnumerable<XElement> | IEnumerable<XElement> | 要素のコレクション |

### 出力先

- XMLファイル
- Stream/TextWriter
- XmlWriter
- 文字列（ToString）

## 処理フロー

### 処理シーケンス

```
1. XML読み込み
   └─ XDocument.Load(uri/stream/reader)
   └─ XDocument.Parse(string)

2. ドキュメント構造の走査
   └─ doc.Root で根要素取得
   └─ element.Elements() で子要素列挙
   └─ element.Descendants() で子孫要素列挙

3. LINQクエリによるデータ抽出
   └─ from e in doc.Descendants("item") where ... select ...

4. ドキュメントの変更
   └─ element.Add(new XElement(...))
   └─ element.SetValue(value)
   └─ element.Remove()

5. 保存・出力
   └─ doc.Save(fileName/stream/writer)
   └─ element.ToString()
```

### フローチャート

```mermaid
flowchart TD
    A[XML読み込み] --> B{データソース}
    B -->|ファイル| C[XDocument.Load]
    B -->|文字列| D[XDocument.Parse]
    B -->|Stream| E[XDocument.Load(stream)]
    C --> F[XDocumentインスタンス]
    D --> F
    E --> F
    F --> G[Root要素取得]
    G --> H{操作種別}
    H -->|検索| I[LINQクエリ/Descendants]
    H -->|変更| J[Add/Remove/SetValue]
    H -->|出力| K[Save/ToString]
    I --> L[結果取得]
    J --> K
    K --> M[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 整形式XML | 読み込むXMLは整形式でなければならない | Load/Parse時 |
| BR-02 | 名前空間処理 | XName = XNamespace + LocalName | 名前空間付きXML |
| BR-03 | イベント通知 | Changing/Changedイベントで変更を通知 | 変更操作時 |
| BR-04 | イミュータブル名前 | XName/XNamespaceはアトム化され再利用 | 常時 |

### 計算ロジック

XNameのアトム化:
- 同じ名前空間+ローカル名は同一インスタンスを返す
- XNamespace.Get(uri)でキャッシュされた名前空間取得

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| XmlException | 例外 | 不正な形式のXML | 整形式XMLを使用 |
| ArgumentNullException | 例外 | 必須パラメータがnull | 有効な値を指定 |
| InvalidOperationException | 例外 | ルート要素が存在しない | ルート要素を追加 |

### リトライ仕様

XML解析エラーは修正不能なため、リトライは通常行わない。

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

本機能はトランザクションを使用しない。メモリ上の変更は即座に反映される。

## パフォーマンス要件

- XDocument/XElementは全体をメモリに読み込む
- 大量データにはXmlReaderとの組み合わせ（ストリーミング）を検討
- XNameのアトム化により名前比較が高速

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

- 外部エンティティ参照（XXE）に注意（デフォルトで無効）
- DTD処理の制御（XmlReaderSettings.DtdProcessing）
- 信頼できないXMLソースへの対策

## 備考

- .NET 3.5で導入
- System.Xml.XPathとの統合（CreateNavigator）
- 非同期メソッド（LoadAsync、SaveAsync）サポート

---

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

### 推奨読解順序

#### Step 1: XDocumentを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | XDocument.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocument.cs` | XMLドキュメント全体を表すクラス |
| 1-2 | XContainer.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs` | 子ノードを持つコンテナの基底クラス |

**主要処理フロー（XDocument.cs）**:
- **27行目**: XDocumentクラス定義、XContainerを継承
- **29行目**: _declarationフィールド（XML宣言）
- **115-119行目**: Declarationプロパティ（XML宣言の取得・設定）
- **124-130行目**: DocumentTypeプロパティ（DTD取得）
- **138-144行目**: NodeTypeプロパティ（XmlNodeType.Document返却）
- **149-155行目**: Rootプロパティ（ルート要素取得）
- **186-189行目**: Load(uri)メソッド（ファイルからの読み込み）
- **294-304行目**: LoadAsync（非同期読み込み）
- **521-524行目**: Parse(text)メソッド（文字列から解析）
- **574-606行目**: Save(stream)メソッド（ストリームへの保存）
- **795-813行目**: WriteTo(writer)メソッド（XmlWriterへの出力）

#### Step 2: XElementを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | XElement.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XElement.cs` | XML要素クラス |
| 2-2 | XAttribute.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XAttribute.cs` | XML属性クラス |

**主要処理フロー（XElement.cs）**:
- **36行目**: XElementクラス定義、XContainerとIXmlSerializableを実装
- **49-50行目**: name、lastAttrフィールド
- **58-63行目**: XElement(XName)コンストラクタ
- **215-218行目**: FirstAttributeプロパティ
- **223-226行目**: HasAttributesプロパティ
- **251-254行目**: IsEmptyプロパティ
- **267-280行目**: Nameプロパティ（名前の取得・設定）
- **303-320行目**: Valueプロパティ（テキスト内容の取得・設定）
- **373-385行目**: Attribute(name)メソッド（属性取得）
- **573-576行目**: Load(uri)メソッド
- **874-877行目**: Parse(text)メソッド

#### Step 3: XContainerを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | XContainer.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs` | コンテナ基底クラス |

**主要処理フロー（XContainer.cs）**:
- **22行目**: XContainerクラス定義（抽象クラス）
- **24行目**: contentフィールド（子コンテンツ格納）
- **53-59行目**: FirstNodeプロパティ
- **64-82行目**: LastNodeプロパティ
- **135-180行目**: Add(content)メソッド（コンテンツ追加）
- **253-256行目**: DescendantNodes()メソッド
- **267-270行目**: Descendants()メソッド（子孫要素取得）
- **294-307行目**: Element(name)メソッド（名前で子要素取得）
- **318-321行目**: Elements()メソッド（子要素列挙）
- **349-360行目**: Nodes()メソッド（子ノード列挙）
- **367-419行目**: RemoveNodes()メソッド（子ノード削除）

#### Step 4: 関連クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | XName.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XName.cs` | XML名前クラス |
| 4-2 | XNamespace.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs` | XML名前空間クラス |
| 4-3 | XNode.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs` | ノード基底クラス |

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

```
XDocument.Load()
├── XmlReader.Create()
├── XDocument.Load(XmlReader, LoadOptions)
│   ├── InitLoad() - XDocument初期化
│   ├── ReadContentFrom(reader, options)
│   │   ├── ContentReader.ReadContentFromContainer()
│   │   │   ├── XElement生成
│   │   │   ├── XAttribute追加
│   │   │   └── AddNodeSkipNotify()
│   │   └── r.Read() - 次のノードへ
│   └── 検証（EOF/Root確認）
└── XmlReader.Dispose()

XElement.Descendants()
├── GetDescendants(name, self)
│   ├── 深さ優先探索
│   ├── 名前マッチング
│   └── yield return element
└── IEnumerable<XElement>返却

XContainer.Add()
├── コンテンツ型判定
│   ├── XNode → AddNode()
│   ├── string → AddString()
│   ├── XAttribute → AddAttribute()
│   └── IEnumerable → 再帰的Add
├── ValidateNode() - ノード検証
├── ConvertTextToNode() - テキストノード化
└── AppendNode() - ノード追加
```

### データフロー図

```
[XMLソース]
     │
     ▼
┌────────────────┐
│  XmlReader     │ ← XmlReaderSettings
└────────────────┘
     │
     ▼
┌────────────────┐
│  ContentReader │ ← 内部クラス
└────────────────┘
     │
     ▼
┌────────────────┐
│   XDocument    │ ← _declaration, content
│      │         │
│      └── Root (XElement)
│           │
│           ├── lastAttr (XAttribute)
│           │
│           └── content (XNode/string)
│                │
│                ├── XElement (子要素)
│                ├── XText (テキスト)
│                ├── XComment (コメント)
│                └── XProcessingInstruction
└────────────────┘
     │
     ▼
[LINQクエリ / 変更操作]
     │
     ▼
┌────────────────┐
│  XmlWriter     │
└────────────────┘
     │
     ▼
[出力先: ファイル/Stream/文字列]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| XDocument.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocument.cs` | ソース | XMLドキュメント |
| XElement.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XElement.cs` | ソース | XML要素 |
| XContainer.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XContainer.cs` | ソース | コンテナ基底 |
| XAttribute.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XAttribute.cs` | ソース | XML属性 |
| XName.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XName.cs` | ソース | XML名前 |
| XNamespace.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNamespace.cs` | ソース | XML名前空間 |
| XNode.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNode.cs` | ソース | ノード基底 |
| XObject.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XObject.cs` | ソース | オブジェクト基底 |
| XText.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XText.cs` | ソース | テキストノード |
| XCData.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XCData.cs` | ソース | CDATAセクション |
| XComment.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XComment.cs` | ソース | コメント |
| XDeclaration.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDeclaration.cs` | ソース | XML宣言 |
| XDocumentType.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XDocumentType.cs` | ソース | ドキュメント型 |
| XProcessingInstruction.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XProcessingInstruction.cs` | ソース | 処理命令 |
| Extensions.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/Extensions.cs` | ソース | LINQ拡張メソッド |
| XNodeReader.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeReader.cs` | ソース | XmlReader実装 |
| XNodeBuilder.cs | `src/libraries/System.Private.Xml.Linq/src/System/Xml/Linq/XNodeBuilder.cs` | ソース | XmlWriter実装 |
