赤紫蘇2 リファレンス

赤紫蘇2 データモデル

akaxiso2.0-beta3


赤紫蘇2リファレンス

1.概要
1.1 赤紫蘇2の構成
1.2 プログラムの
開始から終了まで
1.3 文字コードと
文字コード変換エンジン
1.4 名前空間とQName
1.5 マルチスレッディング

2. 赤紫蘇2データモデル
2.1 チュートリアル
2.2 パーティクル
2.3 aka:sequence
2.3.1 単純型の子要素
2.3.2 複合型の子要素
2.3.1 配列型
2.4 aka::all
2.5 aka:choice
2.5.1 複雑型の子要素
2.5.2 単純型の子要素
2.5.3 バインダクラス
2.5.4 子要素オブジェクト
(aka::item)の扱い
2.5.5 子要素の出現頻度
2.6 属性
2.7 aka:simpleContent
2.8 単純型(aka:simleType)
2.8.1

組み込み型

2.9

配列とポインタ

2.,10 ワイルドカード

3 XMLによる永続化
3.1 シリアライズ
3.2 デシリアライズ

付表
A ライブラリ主要API
B XML Schemaとの
機能対応表
C リリースノート

・赤紫蘇2データモデル

赤紫蘇2は、固有のデータモデルを持っており、これを、赤紫蘇2データモデルと呼びます。このデータモデルは、XMLスキーマの抽象データモデルをベースとして作成されており、大まかに、XMLスキーマ仕様の、「XML Schema Part 1: Structures」における大半の機能と、「XML Schema Part 2: Datatypes」の部分的な機能を、実現します。
また、C++でXMLスキーマのデータモデルと同等の構造を表現した際に、クラス数が少なくなるような最適化も考慮されています。

以下、赤紫蘇2データモデルの考え方について、簡単に説明してゆきます。

・シリアライザブルな値クラスへの要請

シリアライザブルな値クラスは、いわゆるC++のクラスです。classやstructが使用可能です。シリアライザブルな値クラスは、任意の名前空間内、もしくは、グローバル名前空間内にて、宣言することができます。
また、値クラスを(デ)シリアライズするためのXML型情報クラスが別個に定義されます。このクラスをleafクラスと呼びます。このクラスも、任意の名前空間にて(名前の衝突が起こらない限り)宣言、定義可能です。値クラスのデータモデルの構造、タグ名とメンバや要素の対応、出現頻度などの型情報が、leafクラス内で定義されます。

値クラスについては、以下の要請を満たすクラスが、シリアライザブルな値クラスとなります。

  • DefaultConstructiveであること。
    • A a; などの形でインスタンシングできること。
    • 引数つきのコンストラクタのみしかもっていない場合はダメ。
  • CopyConstructiveであること。
    • コピーコンストラクタが使えること。
    • class A { private: A(const A&); }; などとして、コピーコンストラクタが遮蔽されている場合はダメ。
  • 対応するleafクラスが定義されていること。
    • leafクラスによりXML文書へのシリアライズ字の型情報が定義されます。

以上の二つの要請は、STLコンテナの要素となるための要請と同等です。

・二種類の値クラス (classとコンテナ)

値クラスは、値通常のclass、structとコンテナの二種類が用いられます。

通常のクラスについては、いわゆるPOD(Plain Old Data)や、通常のクラスが使用可能です。ただし、値クラスのメンバに対して、leafクラスがアクセス可能である必要があります。これを実現する方法として、friend宣言を用いたり、メンバをpublicにしたりする方法がありますが、方法は、実装者に任されます。

加えて、もう一つの重要な値クラスとして、コンテナがあります。コンテナは、STLコンテナ、もしくは、同等のインターフェースを持つコンテナを使用可能です。

以下の二種類のコンテナを扱うことができます。

順序つきコンテナ(sequential container)

std::list<>、std::vector<>などのように、push_back()メソッドにより、要素を挿入可能であり、挿入された要素が、挿入順に並ぶコンテナです。
順序つきコンテナでは、push_back()メソッド、clear()メソッド、size()、begin()メソッド、end()メソッドを実装しており、iterator型とconst_iterator型に加え、value_type型が使用できる必要があります。以下に、順序つきコンテナとして赤紫蘇が必要とするインターフェースを示します。

template<class I>
struct sequential  {
  typedef I value_type;
  struct iterator (implementation defined.);
  struct const_iterator (implementation defined);

  iterator begin();
  iterator end();

  const_iterator begin() const;
  const_iterator end() const;

  void clear();
  bool empty() const;
  size_t size() const; 
  void push_back(const I& i);
};

・連想コンテナ(associative container)

std::map<>、std::set<>のように、指定されたキーによりコンテナ内の順序付けが可能なコンテナです。
値方として、std::pair<key_type, value_type> が使用でき、insert()メソッド、clear()メソッド、size()メソッド、begin()メソッド、end()メソッドを実装しており、iterator型とconst_iterator型に加え、value_type型が使用できる必要があります。

template<class I>
struct associative  {
  typedef (container defined) value_type;
  struct iterator (implementation defined.);
  struct const_iterator (implementation defined);

  iterator begin();
  iterator end();

  const_iterator begin() const;
  const_iterator end() const;

  void clear();
  bool empty() const;
  size_t size() const; 
  std::pair<value_type, bool> insert(const I& i);
};

現在、sorted associative containerのみに対応しています。

(若干の実装の追加で、multiple associative containerに対応することも、可能です。)

上記以外には、特別の制約はなく、自由なクラス定義を行うことが可能です。

・XML型情報定義クラス(leafクラス)

先ほど述べたように、leafクラスは、任意の名前空間中で定義可能です。ただし、赤紫蘇2では、よく使われる汎用のleafクラスを収める名前空間として、xiso::名前空間を宣言しています。xiso名前空間中の一番重要な宣言は、以下のテンプレートの前置宣言です。

namespace xiso {
  template<class T>
  struct leaf<T>;
};

値クラス、fooに対するleafクラスの定義をxiso::名前空間を使って行う場合は、leaf<>テンプレートクラスを値クラスにより、特殊化します。

namespace xiso {
  template<>
  struct leaf<foo> {
    /* モデル定義の実際の実装 */
  };
};

これにより、xiso::leaf<foo>クラスは、fooクラスのleafクラスとして対応付けられます。xiso::名前空間中のleafクラスは、データモデル定義において、leafクラスが引数として必要な場合のデフォルト引数としても、用いられます。

ただし、値クラスに対して複数のシリアライズ形式が定義可能です。(例:char型の変数を、数値で出力するか、文字で出力するかなど。) xiso::名前空間を用いた場合には、値クラスとleafクラスが、一対一にしか対応しないため、一つの値クラスに対応する複数のleafクラス定義を行うことができません。この場合、xiso::名前空間外でleafクラスを定義する必要があります。

・パーティクルによるデータ構造の記述

赤紫蘇2データモデルでは、データ構造を記述するために、aka:sequence、aka:choice、aka:allという三つのパーティクルを用います。
これらのパーティクルは、<xs:sequence>、<xs:choice>、<xs:all>などのXMLスキーマデータモデルのパーティクルに対応した機能を持っています。また、それぞれのパーティクルは、インスタンシング可能なC++クラスに対してマッピングされます。

aka:sequence、aka:choice、aka:allの詳細については、「赤紫蘇2データモデル パーティクル」をご参照ください。

・テキスト値の扱い(単純型と混合型テキスト)

XMLにおけるテキスト値は、属性値として現れるように値を示す場合と、混合型(mixed)テキストがあります。
値として型を持つようなテキスト値は、XMLスキーマでは<xs:simpleType>として定義可能であり、子要素を持ちません。
これに対して、混合型テキストは、テキストと要素が混在する状態を許します。
赤紫蘇2では、いわゆる単純型として扱われるテキスト値のC++クラス値への相互変換メカニズムを提供します。
また、XMLスキーマで定義されている単純型については、限定的ではありますが、妥当性検証を行うためのコードが実装されています。

その一方、混合型テキストは、赤紫蘇2データモデルでは、処理することができません。これは、赤紫蘇2データモデルの仕様によるものです。この制限は、混合型テキストを処理する場合には、DOMや、より実用途に特化した処理系を用いるほうが効率がよいであろうとの判断に基づいています。

詳細については、「赤紫蘇2データモデル 単純型」をご参照ください。

・<xs:simpleContent>

単純型を値として持つ複雑型として、XMLスキーマでは<xs:simpleContent>を用いることができます。これに対応する赤紫蘇2データモデルとして、aka:simplecontentを仕様することができます。aka:simplecontentは、属性を持つ単純型の要素として扱われます。

詳細については、「赤紫蘇2データモデル aka:simplecontent」をご参照ください。

・<xs:complexContent>

複雑型を拡張・制限する<xs:complexContent>に対応する機能は、赤紫蘇2データモデル中には、ありません。
その一つの理由として、C++では<xs:restriction>の実装が、本質的に困難であることが挙げられます。(継承元のメンバを隠しても、メモリ上のレイアウトには残ってしまう。)
さらに、<xs:extension>、<xs:restriction>を混在させた場合のデータモデルの定義が、複雑となりすぎ、ソースコードの把握が困難となることを考慮しています。


赤紫蘇2トップへ sourceforgeプロジェクトページへ