赤紫蘇2 リファレンス

aka:sequence 複雑型メンバの定義

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 リリースノート

本節では、子要素として複雑型(aka:sequence、aka:all、aka::choice)をメンバに持つaka:sequenceの定義について、説明します。

定義の例

以下、例を用いて、説明します。

定義には、値クラスの宣言とと、その型を指定するleafクラスの宣言、実装が必要です。
ここでは、値クラスを、struct foo、leafクラスを、xiso::leaf<struct foo> とします。

メンバとなるクラスは、複雑型、つまり、赤紫蘇2のパーティクルの値クラスとなります。
これらのクラスは、comp1、comp2...compXという型名を持ち、対応するleafクラスが定義されているものとします。leafクラス名は、compX_leafという名前とします。

struct comp1 のleafクラス、comp1_leafは、aka::sequence<>を継承します。
また、void comp1_leaf::model()メソッド内にて、memberクラス、ptrmemberクラスを用いて、タグ名"member"と、foo::member_を、"ptrmember"と、foo::ptrmember_を対応付けます。

/*値クラスとleafクラスは、あらかじめ、以下の名前で定義されている。 */
struct comp1;
struct comp1_leaf;

struct comp2;
struct comp2_leaf;


/* 値クラス */
struct foo {
  /* 子要素*/
  /* 普通の複雑型子要素 */
  comp1 comp1_;
  /* ポインタ型の複雑型子要素 */
  aka::deep_ptr<comp2> comp2_;
};

/* leafクラス */
namespace xiso {
 struct leaf<foo> : aka::sequence<foo> {
  void model() {
    /* メンバの定義 */
    member("comp1", &foo::comp1_, comp1_leaf());
   /* ポインタ型メンバの定義 */
    ptrmember("comp2", &foo::comp2_, comp2_leaf(),);  
  }
};

attribute(属性)についても、類似の定義を行います。詳細については、「赤紫蘇2データモデル 属性」をご参照ください。

複雑型メンバの種類

複雑型の子要素は、通常の値クラスのみならず、配列型の子要素、グループ参照、ワイルドカード要素(aka::any、aka::any_array、XMLスキーマのxs:anyType)の使用などの用法があります。

モデルグループ参照

モデルグループ参照を行う場合には、タグ名の最初に"&"をつけます。これにより、値クラスのメンバをモデルグループとして参照することができます。上記の例をモデルグループ参照用に書き直すと、以下のようになります。

/* 値クラス */
struct foo {
  /* 子要素*/
  /* 普通の複雑型子要素 */
  comp1 comp1_;
  /* ポインタ型の複雑型子要素 */
  aka::deep_ptr<comp2> comp2_;
};

/* leafクラス */
 struct foo_leaf : aka::sequence<foo> {
  void model() {
    /* メンバの定義 */
    member("&comp1", &foo::comp1_, comp1_leaf());
   /* ポインタ型メンバの定義 */
    ptrmember("&comp2", &foo::comp2_, comp2_leaf(),);  
  }
};

ここで、&comp1、&comp2は、モデルグループ参照として扱われ、<comp1>、<comp2>が、タグ名として現れなくなります。

配列定義の例

複数個表れる要素は、配列により定義されます。赤紫蘇2では、配列を(STL)コンテナにより定義します。(配列の詳細については、「配列とポインタ」をご参照ください。)
配列のleafクラスは、別途、定義される必要があります。データモデル定義では、このleafクラスを用い、メンバの型を定義します。

/*値クラスとleafクラスは、あらかじめ、以下の名前で定義されている。 */
struct comp1;
struct comp1_leaf;

/* 配列クラスは、以下のように定義されている。 */
typedef std::vector<comp1> comp_array;

/* 配列クラスに対するleafクラスを定義する。 */
typedef aka::sequential_array<comp1_array, comp1, comp1_leaf> comp1_array_leaf;

/* 値クラス */
struct foo {
  /* 子要素*/
  /* 普通の複雑型子要素 */
  comp1_array comp1s_;
};

/* leafクラス */
struct foo_leaf : aka::sequence<foo> {
  void model() {
    /* メンバの定義 */
    member("comp1", &foo::comp1_, comp1_leaf(), 0, aka::unbounded);
  }
};

上記定義により、複数の連続する<comp1>タグに対し、値クラスがcomp1の配列となります。
また、model()メソッド中、出現頻度を指定します。この値は、非負の整数となりますが、XMLスキーマのunbounded(上限値の束縛なし)に対応する指定値は、aka::unboundedとなります。
また、モデルグループに対しても、同様の定義が可能です。

ワイルドカード要素

赤紫蘇2の組み込み型として、aka::any、aka::any_arrayを用いることができます。これは、XML Schemaのワイルドカード要素(xs:anyType, xs:any)に対応します。
xs:anyは、ワイルドカード要素として、タグ名も不定となりうるワイルドカード要素であり、xs:anyTypeは、タグ名が規定され、内容モデルがワイルドカードとなります。ワイルドカード要素については、「ワイルドカード要素」をご参照ください。

これらのワイルド要素を使用するには、any()関数を用いて、メンバの宣言を行います。

template<class P>
void any(const std::string &tagname, aka::any P::* m, 
         const std::string ns_list = "#all"); 

第一引数は、タグ名です。通常のタグ名を用いることで、<xs:anyType>、タグ名をモデルグループ参照と同様'&'で開始することにより、<xs:any>と対応する内容モデルが可能です。
第二引数は、aka::any型への配列メンバのポインタです。
第三引数は、ワイルドカード要素が属する名前空間指定です。名前空間は、以下の書式で定義します。

ns_listの値 許される子要素
#all すべての名前空間に属する要素
#other:(名前空間URI) 名前空間URIで示された名前空間以外に属する要素
例: "#other:http://akaxiso.sourceforge.jp/akaxiso2"とすると、"http://akaxiso.sourceforge.jp"のURIで定義される名前空間以外に属する要素、もしくは、ローカルな要素
#local ローカルな要素
スペースで区切られたURIのリスト リストに挙げられたURIのリストに属する要素

aka::any型の配列であるaka::any_arrayを使用する場合、出現頻度指定つきのanyを使用します。

template<class P>
void any(const std::string &tagname, aka::any_array P::* m, int minOccurs, int maxOccurs, 
         const std::string &ns_list = "#all") ;

template<class P>
void any(const std::string &tagname, aka::any_array P::* m, int minOccurs, int maxOccurs, 
         bool emptiable, const std::string &ns_list) ; 

最初の関数は簡略版であり、タグ名、aka::any_arrayメンバへのポインタ、minOccurs、maxOccursを指定します。二つ目の関数は、詳細指定版であり、emptiableの指定が可能です。また、名前空間リストは明示的に指定する必要があります。

タグ名の頭に'&'をつけた場合、<xs:any>のように、タグ名にかかわらず、aka::any、aka::any_arrayにデシリアライズされた内容が書き込まれます。また、頭に'&'をつけない場合、型として、xs:anyTypeを定義したことと同等となり、要素の内容モデルがワイルドカードとなります。

以下に、xs:anyを子要素に持ち、"any"という名前のxs:anyTypeの配列を子要素に持つクラスの定義を示します。出現するタグ名の名前空間に対しては、すべてを許すこととします。

/* 値クラス */
struct foo {
  /* 子要素*/
  /* xs:any */
  aka::any any_;  
 /* xs:anyTypeの配列版 */  
 aka::any_array anys_;
};

/* leafクラス */
struct foo_leaf : aka::sequence<foo> {
  void model() {
    /* メンバの定義 */
    any("&any", &foo::any_ , "#all");
    any("any", &foo::anys_,  0, aka::unbounded, "#all");   
  }
};


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