組み込みの装置を設計していると、装置の状態を集中管理しているサーバに転送する機能が、よく組み込まれます。この場合、通信プロトコルはTCP/IPやHTTPが使用され、データ形式はXMLが使用されます。C言語ではJavaやC#と違って、提供されるXML関連のライブラリがないため、XMLの取り扱い難しくはないが手間がかかります。

XML形式を次のようににした場合、C言語によるロジックを考えてみました。

<devicestatus>
  <server>
    <status>1</status>
    <port1>1,2,3</port1>
    <port2>4,5,6</port2>
  </server>
  <cliant1>
    <status>2</status>
    <port1>2,3,4</port1>
    <port2>5,6,7</port2>
  </cliant1>
  <cliant2>
    <status>3</status>
    <port1>8,7,6</port1>
    <port2>5,4,3</port2>
  </cliant2>
</devicestatus>

XML形式でデータを構成する場合、文字列操作が主になりますが、なるべくできあがったソースを見やすくするために次のことを考えます。

  • XML形式に合わせてストラクチャを作ること
  • 同じデータ形式の情報は、個数をDefineで定義すること
  • 入れ子になっているデータについてはfor文などのループにより処理ができるように、ストラクチャを構成すること

次のCコードは、構造体Device,DeviceStatusを入れ子にして、XML形式にあわせています。また、port[PortNum][DataNum]は、二次元配列とし、ポート番号とデータ番号をそれぞれ引数として、for文でループできる構造を採用しています。またソースを見やすくするため、引数はi,kでなく、cliant,portとして、引数の意味がわかるようにコーティングしています。

#include <stdio.h>

#define Cliant 2	// クライアント数
#define PortNum 2	// ポート数
#define DataNum 3	// データ数

// 一台分の装置の情報ストラクチャ
struct Device{
	char status;
	char port[PortNum][DataNum];
};
// 装置/全体の情報ストラクチャ
struct DeviceStatus{
	struct Device server;
	struct Device cliant[Cliant];
};


int main(int argc, char *argv[]){
	// 初期値設定
	struct DeviceStatus devicestatus = {
		 1, 1, 2, 3, 4, 5, 6,
		 { 
 			{ 2, 2, 3, 4, 5, 6, 7 },
			{ 3, 8, 7, 6, 5, 4, 3 } 
		 }
	};

	printf("<devicestatus>\n");

	printf("<server>\n");	//サーバの装置情報をXML形式に変換する
	printf("<status>%d</status>\n", devicestatus.server.status);
	for (int port = 0; port < PortNum; port++){
		printf("<port%d>%d,%d,%d</port%d>\n", port + 1, devicestatus.server.port[port][0],
			devicestatus.server.port[port][1], devicestatus.server.port[port][2], port + 1);
	}
	printf("</server>\n");

	for (int cliant = 0; cliant < Cliant; cliant++){
		printf("<cliant%d>\n", cliant + 1);	//クライアントの装置情報をXML形式に変換する
		printf("<status>%d</status>\n", devicestatus.cliant[cliant].status);
		for (int port = 0; port < PortNum; port++){
			printf("<port%d>%d,%d,%d</port%d>\n", port + 1, devicestatus.cliant[cliant].port[port][0],
				devicestatus.cliant[cliant].port[port][1], devicestatus.cliant[cliant].port[port][2], port + 1);
		}
		printf("</cliant%d>\n", cliant+1);
	}

	printf("</devicestatus>\n");
	return 0;
}

XML形式で情報を編集する場合、設計時にプログラムの作成しやすさも考慮して、XMLの構造を決めることも必要だと考えます。